The following test scenario is used as an example to illustrate. The script tested at this time is mounted on TestNode1
一、GameObject.Find(string param)
Find by name
The most common method is GameObject.Find, where the parameter can be filled with the name of the object , and it is a global search, which has nothing to do with the node where the script is located. For example, directly search TestNode111 and TestNode22 below, you can find the corresponding point
if (GameObject.Find("TestNode111") != null)
{
Debug.Log("GameObject.Find TestNode111 true");
}
else
{
Debug.Log("GameObject.Find TestNode111 false");
}
if (GameObject.Find("TestNode22") != null)
{
Debug.Log("GameObject.Find TestNode22 true");
}
else
{
Debug.Log("GameObject.Find TestNode22 false");
}
However, since this method searches for global objects, it will consume a lot of performance when there are many objects, so don't call it too frequently. Another thing to note is if there is a node with the same name in the scene. Only the first node found will be returned here, so avoid duplicate names.
Also, when the GameObject.Find parameter is the object name, the node whose active is false cannot be found . You can try to set the active of TestNode111 to false. You can see that this node cannot be found at this time.
Find by path
The parameter can also fill in the path . The path here can be an absolute path or a relative path . The cost of finding a node through the path will be lower than directly based on the object name. The node structure is still as follows
The absolute path starts with "/" or the object name, and the scene name is not in this path. For example, find the point TestNode111 .
The absolute path should be filled with GameObject.Find( "/TestNode1/TestNode11/TestNode111" )
If you fill in GameObject.Find("/TestScene/TestNode1/TestNode11/TestNode111") or GameObject.Find("TestScene/TestNode1/TestNode11/TestNode111"), the corresponding node cannot be found.
Relative paths need to start with the name of the object, not "/"
For example, GameObject.Find("TestNode11/TestNode111") finds success
And GameObject.Find("/TestNode111") failed to find
if (GameObject.Find("TestNode11/TestNode111") != null)
{
Debug.Log("GameObject.Find TestNode11/TestNode111 true");
}
else
{
Debug.Log("GameObject.Find TestNode11/TestNode111 false");
}
if (GameObject.Find("/TestNode1/TestNode11/TestNode111") != null)
{
Debug.Log("GameObject.Find /TestNode1/TestNode11/TestNode111 true");
}
else
{
Debug.Log("GameObject.Find /TestNode1/TestNode11/TestNode111 false");
}
if (GameObject.Find("TestNode1/TestNode11/TestNode111") != null)
{
Debug.Log("GameObject.Find TestNode1/TestNode11/TestNode111 true");
}
else
{
Debug.Log("GameObject.Find TestNode1/TestNode11/TestNode111 false");
}
if (GameObject.Find("TestScene/TestNode1/TestNode11/TestNode111") != null)
{
Debug.Log("GameObject.Find TestScene/TestNode1/TestNode11/TestNode111 true");
}
else
{
Debug.Log("GameObject.Find TestScene/TestNode1/TestNode11/TestNode111 false");
}
if (GameObject.Find("/TestNode111") != null)
{
Debug.Log("GameObject.Find /TestNode111 true");
}
else
{
Debug.Log("GameObject.Find /TestNode111 false");
}
When using the absolute path to find the active value of false, if the active node of the searched node is false and the parent node active is true, the node can still be found . The result is as follows
If you use relative path search, you cannot find the node whose active is false
And when his parent node active is also false, the search will fail, and the results are as follows
二、GameObject.FindWithTag
The logic of GameObject.FindWithTag is basically the same as GameObject.Find, which is also a global search. Similar to GameObject's search function by name, except that the search is based on the Tag attribute, and it is also impossible to find nodes whose active is false.
三.Transform.Find
transform.Find is to find the child node of the mount script node, and only the child node can be found, and the direct Find grandchild cannot be found . If you want to find the grandchild node, you need to call the Find function step by step. And transform.Find can also find nodes whose active is false . The following is the result of directly finding child nodes and grandchild nodes
if (this.transform.Find("TestNode11") != null)
{
Debug.Log("this.transform.Find TestNode11 true");
}
else
{
Debug.Log("this.transform.Find TestNode11 false");
}
if (this.transform.Find("TestNode111") != null)
{
Debug.Log("this.transform.Find TestNode111 true");
}
else
{
Debug.Log("this.transform.Find TestNode111 false");
}
Fourth, the method of obtaining the root node whose active is false
Because transform can find nodes whose active is false through the hierarchical relationship. So using transform.Find can basically find all the nodes in the scene. For the root node that is not on the node tree of this Transfrom, such as TestNode2 in the example, if active is true, you can also use GameObject.Find to find it directly.
But there is also a special case, that is, the root node whose active is false is not on the same node tree, and TestNode2 in the following figure is the root node whose active is false.
There are two ways
UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects()
Resources.FindObjectsOfTypeAll(typeof(GameObject))
code show as below
GameObject[] allRoot = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects();
for (int i = 0; i < allRoot.Length; i++)
{
if (allRoot[i].name == "TestNode2")
{
Debug.Log("GetRootGameObjects find TestNode2 true");
break;
}
}
GameObject[] all = Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[];
for (int i = 0; i < all.Length; i++)
{
var item = all[i];
if (item.scene.isLoaded)
{
if (item.name == "TestNode2")
{
Debug.Log("FindObjectsOfTypeAll find TestNode2 true");
break;
}
}
}
You can see the results below, both methods can successfully find TestNode2