在Unity中开发游戏时,我正在大量使用[RequireComponent(typeof(%ComponentType%))]
以确保组件满足所有依赖性。
我现在正在实现一个突出各种UI对象的教程系统。要进行突出显示,我要引用GameObject
场景中的,然后使用Instantiate()克隆它,然后以递归的方式删除显示不需要的所有组件。问题在于,随着RequireComponent
这些组件的广泛使用,许多组件无法简单地以任何顺序删除,因为它们由尚未删除的其他组件所依赖。
我的问题是:有没有一种方法可以确定是否Component
可以将a 从GameObject
当前连接的对象中删除。
我发布的代码在技术上可以正常工作,但是会引发Unity错误(如图所示,未在try-catch块中捕获)
这是代码:
public void StripFunctionality(RectTransform rt)
{
if (rt == null)
{
return;
}
int componentCount = rt.gameObject.GetComponents<Component>().Length;
int safety = 10;
int allowedComponents = 0;
while (componentCount > allowedComponents && safety > 0)
{
Debug.Log("ITERATION ON "+rt.gameObject.name);
safety--;
allowedComponents = 0;
foreach (Component c in rt.gameObject.GetComponents<Component>())
{
//Disable clicking on graphics
if (c is Graphic)
{
((Graphic)c).raycastTarget = false;
}
//Remove components we don't want
if (
!(c is Image) &&
!(c is TextMeshProUGUI) &&
!(c is RectTransform) &&
!(c is CanvasRenderer)
)
{
try
{
DestroyImmediate(c);
}
catch
{
//NoOp
}
}
else
{
allowedComponents++;
}
}
componentCount = rt.gameObject.GetComponents<Component>().Length;
}
//Recursive call to children
foreach (RectTransform childRT in rt)
{
StripFunctionality(childRT);
}
}
因此,此代码生成上面调试日志的最后三行的方式如下:将a作为输入GameObject
包含两个组件:Button
和PopupOpener
。PopupOpener
要求Button
组件存在于具有以下内容的同一个GameObject中:
[RequireComponent(typeof(Button))]
public class PopupOpener : MonoBehaviour
{
...
}
while循环的第一个迭代(由文本“ ITERATION ON Button Invite(clone)”表示)试图删除第Button
一个,但是不能删除,因为它取决于PopupOpener
组件。这引发了错误。然后,它尝试删除PopupOpener
它所做的组件,因为它不受任何其他依赖。在下一个迭代中(由第二个文本“ ITERATION ON Button Invite(clone)”表示),它试图删除Button
现在可以执行的剩余组件,因为它PopupOpener
是在第一次迭代中(在错误之后)被删除的。
所以我的问题是,是否可以提前检查是否可以在GameObject
不调用Destroy()
或的情况下将指定的组件从当前组件中删除DestroyImmediate()
。谢谢。
Destroy
删除了帧末尾的组件(与Immediate
ly 相对)。DestroyImmediate
无论如何都被认为是不好的风格,但是我想切换到Destroy
实际上可以消除这些错误。