美文网首页Unity&iOS
Unity Gameobject Transform

Unity Gameobject Transform

作者: 合肥黑 | 来源:发表于2021-11-19 22:52 被阅读0次

参考
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的引用吧。毕竟倘若一大堆东西的话,能快不少呢。

相关文章

网友评论

    本文标题:Unity Gameobject Transform

    本文链接:https://www.haomeiwen.com/subject/znbbaltx.html