最近面试被问到了一个问题,GameObjet.Find和Transform.Find的区别有哪些,因为比较久远,所以记得不是很清晰,答完感觉不太对,又专门回来做一下测试。
其他面试题集合:
这应该是一个比较常见的Unity相关问题,我们从API开始进行分析,然后进行试验。
1. 从API上简单分析
//GameObject
//
// 摘要:
// Finds a GameObject by name and returns it.
//
// 参数:
// name:
[FreeFunction(Name = "GameObjectBindings::Find")]
public static GameObject Find(string name);
//Transform
//
// 摘要:
// Finds a child by n and returns it.
//
// 参数:
// n:
// Name of child to be found.
//
// 返回结果:
// The returned child transform or null if no child is found.
public Transform Find(string n);
从API上能看出来什么呢?
- 从成员方法类型上就有差别:Gameobject.find是一个静态方法,而Transform.find是一个实例方法,这意味着什么呢?Transform方法是需要一个实例的,因为Transform是一个Component,所以它很可能也会受GameObject的active状态影响;
- 从返回类型上来说,Gameobject.find的返回值也是一个GameObject,而Transform.find的返回值是一个Transform;
- 一般情况下,路径查找也是一个比较常见的功能,这两个又是否支持呢?
2. 开始测试
- 首先我们构造这么几个GameObject:
这里一共五个GameObject,其中只有unactive一个的activeSelf状态是false,其他都为ture - 创建脚本并挂载在root之上,并在start中编写如下代码:
void Start()
{
GameObject abcdeObj = GameObject.Find("abcde");
if(null != abcdeObj)
{
Debug.Log("成功找到abcdeObj ——查找不存在的物体");
}
else
{
Debug.Log("无法找到abcdeObj ——查找不存在的物体");
}
GameObject active_temp = GameObject.Find("active");
if(null != active_temp)
{
Debug.Log("成功找到acitve ——查找active的物体");
}
else
{
Debug.Log("无法找到acitve ——查找active的物体");
}
GameObject unactive_temp = GameObject.Find("unactive");
if (null != unactive_temp)
{
Debug.Log("成功找到unactive ——查找一个unactive");
}
else
{
Debug.Log("无法找到unactive ——查找一个unactive");
}
GameObject active_child_1 = GameObject.Find("active_child");
if (null != active_child_1)
{
Debug.Log("成功找到active_child ——直接查找active");
}
else
{
Debug.Log("无法找到active_child ——直接查找active");
}
GameObject unactive_child_1 = GameObject.Find("unactive_child");
if (null != unactive_child_1)
{
Debug.Log("成功找到unactive_child ——直接查找查找一个unactive_child");
}
else
{
Debug.Log("无法找到unactive_child ——直接查找查找一个unactive_child");
}
GameObject active_child_2 = GameObject.Find("active/active_child");
if (null != active_child_2)
{
Debug.Log("成功找到active_child ——通过层级路径查找一个active的物体");
}
else
{
Debug.Log("无法找到active_child ——通过层级路径查找一个active的物体");
}
GameObject unactive_child_2 = GameObject.Find("unactive/unactive_child");
if (null != unactive_child_2)
{
Debug.Log("成功找到unactive_child ——通过层级路径查找一个unactive_child");
}
else
{
Debug.Log("无法找到unactive_child ——通过层级路径查找一个unactive_child");
}
GameObject active_child_3 = GameObject.Find("root/active/active_child");
if (null != active_child_3)
{
Debug.Log("成功找到active_child——通过root开始查找一个active的物体");
}
else
{
Debug.Log("无法找到active_child——通过root开始查找一个active的物体");
}
GameObject unactive_child_3 = GameObject.Find("root/unactive/unactive_child");
if (null != unactive_child_3)
{
Debug.Log("成功找到unactive_child——通过root开始查找一个unactive的物体");
}
else
{
Debug.Log("无法找到unactive_child——通过root开始查找一个unactive的物体");
}
Debug.Log("--------以下是Transform查找---------");
Transform unactive_transform = transform.Find("unactive");
if (null != unactive_transform)
{
Debug.Log("成功找到unactiveTransform ——直接查找unactive");
}
else
{
Debug.Log("无法找到unactiveTransform ——直接查找unactive");
}
//越级查找一个activeself为false的Transform
Transform unactive_child_Transform_0 = transform.Find("unactive");
if (null != unactive_child_Transform_0)
{
Debug.Log("成功找到unactiveTransform ——越级查找 ");
}
else
{
Debug.Log("无法找到unactiveTransform ——越级查找 ");
}
//在一个activeself为false的Transform下查找一个transform
if (null != unactive_transform)
{
Transform unactive_child_Transform_1 = unactive_transform.Find("unactive_child");
if (null != unactive_child_Transform_1)
{
Debug.Log("成功找到unactiveChildTransform ——父transform直接查找");
}
else
{
Debug.Log("无法找到unactiveChildTransform ——父transform直接查找");
}
}
//使用完整路径查找一个Transform
Transform unactive_child_Transform_2 = transform.Find("root/unactive/unactive_child");
if (null != unactive_child_Transform_2)
{
Debug.Log("成功找到unactive_child_Transform_2 ——使用完整路径查");
}
else
{
Debug.Log("无法找到unactive_child_Transform_2 ——使用完整路径查");
}
//使用相对tranform的路径查找一个Transform
Transform unactive_child_Transform_3 = transform.Find("unactive/unactive_child");
if (null != unactive_child_Transform_3)
{
Debug.Log("成功找到unactive_child_Transform_3 ——使用相对tranform的路径");
}
else
{
Debug.Log("无法找到unactive_child_Transform_3 ——使用相对tranform的路径");
}
}
基本逻辑很简单,就是进行一组一组的对比,下面是结果:
3. 测试和对比论
- 无论是物体自身原因还是它父物体的原因,只要它在Hierarchy中的active是false,那么就无法使用GameObject.Find找到,使用任何寻找方式都无法获取一个active为false的GameObject;
- 无论物体的active状态是true还是false,都可以使用Transform来找到;
- 两种Find都支持使用路径查找,但是只有GameObject支持使用超过脚本所在位置的路径进行查找,Transform的Find仅支持从子物体开始的路径查找;
4. 总结不同之处
从API开始,可以得出下面几条:
- 从成员方法类型上就有差别:Gameobject.find是一个静态方法,而Transform.find是一个实例方法;
- 从返回类型上来说,Gameobject.find的返回值也是一个GameObject,而Transform.find的返回值是一个Transform;
- 无论是物体自身原因还是它父物体的原因,只要它在Hierarchy中的active是false,那么就无法使用GameObject.Find找到,使用任何寻找方式都无法获取一个active为false的GameObject;而无论物体的active状态是true还是false,都可以使用Transform来找到;
- 两种Find都支持使用路径查找,但是只有GameObject支持使用超过脚本所在位置的路径进行查找,Transform的Find仅支持从子物体开始的路径查找;