【问题标题】:How to find child of a GameObject or the script attached to child GameObject via script如何通过脚本查找 GameObject 的子对象或附加到子 GameObject 的脚本
【发布时间】:2017-04-06 17:33:51
【问题描述】:

我知道这是一个有点愚蠢的问题,但是我将如何通过脚本引用游戏对象的子对象(立方体)(脚本附加到游戏对象)。 (相当于GetComponent之类的东西)

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    按索引查找子游戏对象:

    您可以使用GetChild 函数获取游戏对象的第一个子对象。

    GameObject originalGameObject = GameObject.Find("MainObj");
    GameObject child = originalGameObject.transform.GetChild(0).gameObject;
    

    您可以通过将子游戏对象的索引号(例如 1、2、3)提供给GetChild 函数来获取其他子对象。

    如果它是原始游戏对象中的孩子的孩子?我会不会 必须重复它,否则它只是第n个吗

    你先找到孩子,然后从引用中找到那个孩子的孩子。

    假设这是 OriginalGameObject/Prefab 层次结构:

    • 原始游戏对象
    • 孩子1
    • 孩子2
    • 孩子3
      • childOfChild3

    如您所见,OriginalGameObject 是child1、child2 和child3 的父级。 childOfChild3 是child3 的孩子。

    假设你想访问childs,而你只需要引用OriginalGameObject,它是父游戏对象:

    //Instantiate Prefab
    GameObject originalGameObject  = Instantiate(prefab);
    
    //To find `child1` which is the first index(0)
    GameObject child1 = originalGameObject.transform.GetChild(0).gameObject;
    
    //To find `child2` which is the second index(1)
    GameObject child2 = originalGameObject.transform.GetChild(1).gameObject;
    
    //To find `child3` which is the third index(2)
    GameObject child3 = originalGameObject.transform.GetChild(2).gameObject;
    

    索引从0开始,所以真正的索引号是index-1,就像数组一样。

    现在,要获取 childOfChild3 的引用,它是 child3 的子代,但您只有 OriginalGameObject 的引用,它是父 GameObject:

    首先,获取child3 的引用,然后从中获取childOfChild3。

    GameObject mychild = originalGameObject.transform.GetChild(2).gameObject;
    GameObject childOfChild3 = mychild.transform.GetChild(0).gameObject;
    

    使用循环按索引查找 [all] 子游戏对象:

    循环遍历 originalGameObject 的所有子对象:

    GameObject originalGameObject = Instantiate(prefab);
    for (int i = 0; i < originalGameObject.transform.childCount; i++)
    {
        GameObject child = originalGameObject.transform.GetChild(i).gameObject;
        //Do something with child
    }
    

    您还可以使用transform.FindChild 函数按名称查找孩子。我不建议您这样做。当多个孩子共享相同的名字时,它似乎很慢并且会发生冲突。这就是你使用GetChild的原因。

    按名称查找子游戏对象:

    GameObject child1 = originalGameObject.transform.FindChild("child1").gameObject;
    GameObject child2 = originalGameObject.transform.FindChild("child2").gameObject;
    GameObject child3 = originalGameObject.transform.FindChild("child3").gameObject;
    

    要查找childOfChild3,您可以使用“/”轻松完成,就像使用文件目录一样。您提供 parent/child 然后名称。 childOfChild3 的父级是 child3。所以,我们在 FindChild 函数中使用 childOfChild3/child3。

    GameObject childOfChild3 = originalGameObject.transform.FindChild("child3/childOfChild3").gameObject;
    

    查找附加到子游戏对象的脚本/组件:

    如果你想要的只是附加到子游戏对象的脚本,那么使用GetComponentInChildren:

    MyScript childScript = originalGameObject.GetComponentInChildren<MyScript>();
    

    如果有多个孩子使用相同的脚本,而您只想获得所有附加到他们的脚本,则使用GetComponentsInChildren:

    MyScript[] childScripts = originalGameObject.GetComponentsInChildren<MyScript>();
    for (int i = 0; i < childScripts.Length; i++)
    {
        MyScript myChildScript = childScripts[i];
        //Do something with myChildScript
    }
    

    【讨论】:

    • 程序员,只有第一个??
    • 检查更新。你说的是孩子不是孩子,所以我假设只有一个孩子。 Knetic 提供的答案/代码甚至不应该在 Unity 5 上编译。
    • 如果它是原始游戏对象中孩子的孩子?我是否只需要重复它还是只是第n个呢
    • 其实等等,有办法吗?
    • 等一下。我正在编辑我的答案来回答这个问题。
    【解决方案2】:

    gameObject.transform.children 包含给定游戏对象的所有直接子级。您可以遍历它并找到所需的孩子。例如,按名称;

    for(int i = 0; i < gameObject.transform.childCount;)
    {
        if(gameObject.transform.children[i].name == "someName")
        {
            // do what you need with it
        }
    
    }
    

    有几种迭代方法。您可以使用枚举,如these docs 中所示,或使用FindChild。

    如果您有一些其他条件,例如想要找到具有特定类型组件的子项,而不仅仅是按名称,通常您会想要遍历子项。

    【讨论】:

    • 非常感谢,我可以在 11 分钟内先接受这个答案,但别担心,我会...
    • 只是一件事,你确定没有更简单的方法
    • 我刚刚更新了一些按名称查找的便捷方法,以及一些关于何时需要迭代子项与使用 FindChild 的说明
    【解决方案3】:

    我发现这个非常短的方法只有 2 行, 我的播放器层次结构是这样的:

    -播放器

    1. 头
    2. 子弹位置

    代码:

    Transform[] ObjectChildrens;
    ObjectChildrens = gameObject.GetComponentsInChildren<Transform>();
    GameObject Head = System.Array.Find(ObjectChildrens, p => p.gameObject.name == "Head").gameObject;
    
    
    GameObject BulletPos = System.Array.Find(ObjectChildrens, p => p.gameObject.name == "BulletPos").gameObject;
    GameObject LifeProgresBar = System.Array.Find(ObjectChildrens, p => p.gameObject.name == "LifeProgresBar").gameObject.GetComponent<Text>().text = "100";
    CapsuleCollider2D cc = System.Array.Find(ObjectChildrens, p => p.gameObject.name == "HeadPlace").gameObject.GetComponent<CapsuleCollider2D>();
    

    【讨论】:

      【解决方案4】:

      你可以在父游戏对象中有公共变量。

      public Tranform childGameObject;

      然后将您的子游戏对象分配给它。

      这样可以避免隐藏的依赖关系。以及您的子立方体可以在另一个父级和另一个父级内部。

      【讨论】:

      • gabs,这不起作用,因为正在实例化游戏对象,我需要对该实例的子对象的引用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-17
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多