我在场景中有一个预制件,我想要接触那个预制件的孩子,该预制件的结构是这样的:
PauseMenu
UI_Resume
TextField
TextField2
UI_Side_Back <---- (I need this child)
UI_Home
transform.FindChild
只返回第一级子级,loop
该转换也是第一级子级循环:
foreach (Transform item in PooledPause.transform) {
Debug.Log(item.name);
}
我认为它需要是一种递归方法或其他东西。我怎么能找到那个孩子?
答案 0 :(得分:10)
您可以使用路径查找转换:
var target = transform.Find("UI_Resume/TextField2/UI_Side_Back");
来自documentation for Transform.Find
:
如果name包含'/'字符,它将像路径名一样遍历层次结构。
答案 1 :(得分:1)
我之前不为Unity3D开发,但我建议您为对象设置标签并按标签搜索。像this:
public static T FindComponentInChildWithTag<T>(this GameObject parent, string tag)where T:Component{
Transform t = parent.transform;
foreach(Transform tr in t)
{
if(tr.tag == tag)
{
return tr.GetComponent<T>();
}
else
{
tr.GetComponent<T>().FindComponentInChildWithTag(tag);
}
}
}
或者喜欢this。
但如果您真的想按名称搜索,可以将之前的代码更改为this:
if(tr.name == "object name")
或者像这样做一个find():
tr.Find("Bone");
//or
parent.Find("UI_Resume/TextField2/UI_Side_Back");
答案 2 :(得分:1)
感谢Dan Puzey
的回答,另外如果您想对对象进行递归循环,可以像这样实现:
void Start()
{
GameObject theChild = RecursiveFindChild (theParentGameObject.transform, "The Child Name You Want");
}
GameObject RecursiveFindChild(Transform parent, string childName)
{
foreach (Transform child in parent) {
if(child.name == childName)
return child.gameObject;
else
return RecursiveFindChild(child, childName);
}
return null;
}
答案 3 :(得分:1)
我尝试了所有解决方案,但没有一个对我有用。无法使用Unity Find
,因为我不知道孩子父母的名字。仅当您的父母只有一个孩子时,此处的递归解决方案才有效,我也不是这种情况。因此,我创建了以下通用递归查找器,它们可在任何类型的GameObject
层次结构(或树)中使用。
public static Transform RecursiveFindChild(Transform parent, string childName)
{
Transform child = null;
for (int i = 0; i < parent.childCount; i++)
{
child = parent.GetChild(i);
if (child.name == childName)
{
break;
}
else
{
child = RecursiveFindChild(child, childName);
if (child != null)
{
break;
}
}
}
return child;
}
注意:请谨慎使用,避免使用大GameObject
树。
答案 4 :(得分:1)
如果您不知道父对象的名称,实现此目的的一种方法是使用它:
Transform GetChildWithName(GameObject go, string childName)
{
Transform child = null;
foreach (Transform t in go.GetComponentsInChildren<Transform>())
{
if (t.name == childName)
{
child = t;
break;
}
}
return child;
}
答案 5 :(得分:0)
上面的“ RecursiveChildFind”不起作用,因为它将仅搜索一个孩子,而不是全部孩子。工作版本如下:
Transform RecursiveFindChild(Transform parent, string childName)
{
foreach (Transform child in parent)
{
if(child.name == childName)
{
return child;
}
else
{
Transform found = RecursiveFindChild(child, childName);
if (found != null)
{
return found;
}
}
}
return null;
}
答案 6 :(得分:0)
尝试此递归方法。
public static Transform RecursiveFindChild(Transform parent, string childName)
{
Transform result = null;
foreach (Transform child in parent)
{
if (child.name == childName)
result = child.transform;
else
result = RecursiveFindChild(child, childName);
if (result != null) break;
}
return result;
}
答案 7 :(得分:0)
这是另一种解决方案,可让您根据任何标准查找任何深度的子项。它使用深度优先的方法。因此,我建议将感兴趣的对象尽可能放在树的高处,以节省一些操作。
它是这样使用的:parent.FindRecursive("child");
或者如果您需要更多灵活性:parent.FindRecursive(child => child.GetComponent<SpriteRenderer>() != null && child.name.Contains("!"));
using System;
using UnityEngine;
public static class TransformExtensions
{
public static Transform FindRecursive(this Transform self, string exactName) => self.FindRecursive(child => child.name == exactName);
public static Transform FindRecursive(this Transform self, Func<Transform, bool> selector)
{
foreach (Transform child in self)
{
if (selector(child))
{
return child;
}
var finding = child.FindRecursive(selector);
if (finding != null)
{
return finding;
}
}
return null;
}
}
答案 8 :(得分:0)
也可以加入我的版本。 如何按名称查找 Child Child。
对更新循环不友好。
public GameObject FindChildGameObjectByName(GameObject go, string gameObjectName)
{
GameObject retrunGO = null;
for (int i = 0; i < go.transform.childCount; i++)
{
if (go.transform.GetChild(i).name == gameObjectName)
{
retrunGO = go.transform.GetChild(i).gameObject;
}
GameObject tmp = FindChildGameObjectByName(go.transform.GetChild(i).gameObject, gameObjectName);
retrunGO = (tmp != null ? tmp : retrunGO);
}
return retrunGO;
}