您现在的位置是:首页 >技术杂谈 >【Unity入门】17.脚本访问父子结点网站首页技术杂谈

【Unity入门】17.脚本访问父子结点

Lampard猿奋 2023-06-04 20:00:02
简介【Unity入门】17.脚本访问父子结点

【Unity入门】脚本访问父子结点

    大家好,我是Lampard~~

    欢迎来到Unity入门系列博客,所学知识来自B站阿发老师~感谢 

(一)父级节点

(1)访问父级节点

    父子关系我们并不陌生,在cocos中常用node:getParent()来获取父级,node:getChild()来获取子级结点,那在unity中是怎么调用的呢?

    在unity中比较奇怪,它的父子关系是记录在transform组件上的(这可能也是transform不可被删除的原因?),因此我们获得父节点可以通过下面的代码

Transform parentTransform = this.transform.parent;

    值得注意的是,通过Transform获得的父级,也是Transform类型的组件,如果我想要访问父级结点这个对象,是需要多加一步操作:

Transform parentTransform = this.transform.parent;
GameObject parent = parentTransform.gameObject;

(2)修改父级结点

    我们可以访问到父级结点,还可以通过tranform.SetParent修改物体的父子关系,比如当前的父子关系如下:

    我们创建一个船新的ParentLogic脚本挂载在BBB物体上

    首先在start中打印父类的名字,然后在update监听鼠标点击动作,点击时就把BBB结点的父类切换至CCC,代码如下:

    void Start()
    {
        Transform parentTransform = this.transform.parent;
        GameObject parent = parentTransform.gameObject;
        Debug.Log("父类的名称是:" + parent.name);
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            GameObject newParent = GameObject.Find("CCC");
            this.transform.SetParent(newParent.transform);
        }
    }

    可以看到,一开始父类的名字是AAA,执行点击后,父类就变成CCC了

(二)子节点

(1)遍历所有子节点foreach

    如果我们想遍历所有的子节点,我们可以通过foreach这个方法实现,它的语法如下:

foreach(Transform child in transform)
{
    // DO SOMETHING
}

    其中child是transform组件下面的所有子transform组件,因此我们可以通过这样的代码来访问所有子节点的名称

foreach(Transform child in transform)
{
    GameObject childObj = child.gameObject;
    Debug.Log("子物体名称为:" + childObj.name)
}

    比如现在AAA结点下面有BBB,CCC,DDD,子结点,其中DDD子节点有一个EEE孙子结点,看看打印效果怎么样

     代码如下:

    void Start()
    {
        GameObject AAA = GameObject.Find("AAA");
        foreach (Transform child in AAA.transform)
        {
            GameObject childObj = child.gameObject;
            Debug.Log("子物体名称为:" + childObj.name);
        }
    }

     可以看到,打印的结果把三个子节点都打出来了,但是孙子结点EEE并没有,所以如果我们想获得子节点中的某一个,我们可以在foreach的时候加一个If name == XXX 的判断

(2)直接精准查找某一个子节点

    之前我们不建议使用GameObject.Find来寻找物体,一方面容易重名,另一方面比较耗,那如果我们想精准找到结点下的某个子节点,就只能foreach去寻找了吗?

    unity的transform组件给我们提供了一个Find方法,和GameObject的FInd一样,需要传入物体的名字或者路径,好处就是,它是精准在它的子节点之间寻找,这样无论从损耗和精准性都强很多

    void Start()
    {
        GameObject AAA = GameObject.Find("AAA");
        Transform BBB =  AAA.transform.Find("BBB");
        Debug.Log(BBB.gameObject.name);
    }

好啦今天就到这里,谢谢各位感谢阅读!!!
点赞,关注!!!

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。