参考
Unity3d 之 理解Gameobject ,gameObject,Transform,transform的区别和关联
GameObject.Find与Transform.Find的区别
【Unity3D游戏开发】GameObject.Find()、Transform.Find查找隐藏对象 (十)
一、Gameobject Transform
1.二者的含义
image.png
- Gameobject是一个类型,所有的游戏物件都是这个类型的对象。gameobject是一个对象, 指的是这个脚本所附着的游戏物件。
- Transform是一个类,用来描述物体的位置,大小,旋转等等信息。transform是Transform类的对象,依附于每一个物体。也是当前游戏对象的一个组件(每个对象都会有这个组件)
void Start()
{
Text lal = this.gameObject.GetComponent<Text>(); //通过gameObject获取到Text组件.
var s = this.gameObject.transform.localPosition.ToString();
Debug.Log("Text" + lal.text + s); //打印获取到组件的中的text的属性
GameObject.Find("a");
this.transform.Find("b");
}
2.Find
两者返回的类型是不同的:
public static GameObject Find(string name);
public Transform Find(string n);
- GameObject.Find只能查找到active的物体,隐藏的查不到。
- GameObject.Find的name如果指定路径,则按路径查找;否则递归查找,直到查找到第一个符合条件的GameObject或者返回null
- transform.Find用于查找子节点,它并不会递归的查找物体,也就是说它只会查找它的子节点,并不会查找子节点的子节点。
3.transfrom.Find不递归查找的例子
image.png
public class TestFind : MonoBehaviour
{
public string testName = "";
// Start is called before the first frame update
void Start()
{
Transform t = transform.Find(testName);
if (t != null)
print("找到了");
else
{
print("没找到");
}
}
}
把这个脚本挂在testfind节点上,指定testName为a或b时,可以找到。而指定为aa或bb时,结果是没找到。此时可以传路径进去,指定为a/aa时,发现又可以找到了。这就说明了 transform.Find不会递归查找。
在实际开发中可能遇到这样的情况,给定一个节点,在这个子节点中递归的查找符合条件的节点。transform.Find不能递归查找,不能直接使用,GameObject.Find又做了很多无用功,关键若是重名还不一定能满足需求。于是我们可以自己写一个递归程序:
public static Transform FindChildRecursively(Transform parent, string name)
{
Transform t = null;
t = parent.Find(name);
if (t == null)
{
foreach (Transform tran in parent)
{
t = FindChildRecursively(tran, name);
if (t != null)
{
return t;
}
}
}
return t;
}
}
4.Find查找隐藏节点的例子
image.png
void Start () {
// GameObject.Find
{
// 根节点
GameObject.Find("A11"); // true
// 父节点(受父节点影响)
GameObject.Find("A21"); // false
GameObject.Find("A22"); // true
// 孙子节点(受父节点影响)
GameObject.Find("A31"); // false
GameObject.Find("A32"); // false
GameObject.Find("A33"); // false
GameObject.Find("A34"); // true
GameObject.Find("A34"); // true 相对路径查找
GameObject.Find("/A34"); // false 绝对路径查找
GameObject.Find("/A11/A22/A34"); // true
GameObject.Find("A11/A22/A34"); // true
GameObject.Find("/A22/A34"); // false
GameObject.Find("A22/A34"); // true
}
// Transform.find
{
// 根节点
Transform A11 = transform.Find("A11"); // false
// 父亲节点
Transform A21 = transform.Find("A21"); // true
Transform A22 = transform.Find("A22"); // true
// 孙子节点
Transform A31 = transform.Find("A31"); // false
Transform A32 = transform.Find("A32"); // false
Transform A33 = transform.Find("A33"); // false
Transform A34 = transform.Find("A34"); // false
// 使用相对于根节点的查找目录
Transform AA31 = transform.Find("A21/A31"); // true
Transform AA32 = transform.Find("A21/A32"); // true
Transform AA33 = transform.Find("A22/A33"); // true
Transform AA34 = transform.Find("A22/A34"); // true
// 包含根节点的查找目录
Transform AA311 = transform.Find("A11/A21/A31"); // false
Transform AA321 = transform.Find("A11/A21/A32"); // false
Transform AA331 = transform.Find("A11/A22/A33"); // false
Transform AA341 = transform.Find("A11/A22/A34"); // false
// 绝对路径
Transform AA3111 = transform.Find("/A11/A21/A31"); // false
Transform AA3211 = transform.Find("/A11/A21/A32"); // false
Transform AA3311 = transform.Find("/A11/A22/A33"); // false
Transform AA3411 = transform.Find("/A11/A22/A34"); // false
}
}
二、提高this.transform的效率
参考 unity3d 提高this.transform的效率
正常来说,大部分同学一般get transform都直接gameobject.transform使用。但往往,你会发现有些人会将transform引用保存起来,例如:
private Transform myTransform;
void Awake() {
myTransform = transform;
}
然后使用myTransform替代this.transform。如果你不知道u3d内部实现获取方式你肯定会以为这人脑抽水了,有直接的不用,还自己保存起来。
在Visual Studio中按F12进入定义可以看到,这些属性都是getter。我们的每一次调用,Unity内部会从GameObject里搜寻这些Component,会有一定的损耗。估计大概的效率(没测试,以后有时间再弄,大家可以参考下文章最后的链接):
GetComponent是this.transform的10倍消耗时间。
this.transform是保存了引用myTransform的1.5倍的消耗时间。(因为新版优化了不少)
实际上如果你是偶尔调用一下transform的话,那就不要保留它的引用了,直接this.transform。如果是Update中,每一帧都要改变的话,还是保留一下this.transform的引用吧。毕竟倘若一大堆东西的话,能快不少呢。












网友评论