如何通过脚本查找 GameObject 的子对象或附加到子 GameObject 的脚本
Posted
技术标签:
【中文标题】如何通过脚本查找 GameObject 的子对象或附加到子 GameObject 的脚本【英文标题】:How to find child of a GameObject or the script attached to child GameObject via script 【发布时间】:2017-04-06 17:33:51 【问题描述】:我知道这是一个有点愚蠢的问题,但是我将如何通过脚本引用游戏对象的子对象(立方体)(脚本附加到游戏对象)。 (相当于GetComponent之类的东西)
【问题讨论】:
【参考方案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 行, 我的播放器层次结构是这样的:
-播放器
-
头
子弹位置
代码:
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,这不起作用,因为正在实例化游戏对象,我需要对该实例的子对象的引用以上是关于如何通过脚本查找 GameObject 的子对象或附加到子 GameObject 的脚本的主要内容,如果未能解决你的问题,请参考以下文章
Unity Editor 脚本用指定 GameObject 的子级填充序列化数组 [关闭]
如何查找场景中所有的物体啊,包括在Hierarchy中不显示的物体