Ao desenvolver um jogo no Unity, estou fazendo uso liberal [RequireComponent(typeof(%ComponentType%))]para garantir que os componentes tenham todas as dependências atendidas.
Agora estou implementando um sistema de tutorial que destaca vários objetos da interface do usuário. Para fazer o realce, estou fazendo uma referência à GameObjectcena, clono-a com Instantiate () e retiro recursivamente todos os componentes que não são necessários para exibição. O problema é que, com o uso liberal RequireComponentdesses componentes, muitos não podem ser simplesmente removidos em nenhuma ordem, pois dependem de outros componentes, que ainda não foram excluídos.
Minha pergunta é: Existe uma maneira de determinar se um Componentpode ser removido do GameObjectque está atualmente anexado.
O código que estou postando funciona tecnicamente, no entanto, gera erros do Unity (não capturados no bloco try-catch, como visto na imagem
Aqui está o código:
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);
}
}
Portanto, a maneira como esse código gerou as últimas três linhas do log de depuração acima é o seguinte: Ele tomou como entrada a GameObjectcom dois componentes: Buttone PopupOpener. PopupOpenerrequer que um Buttoncomponente esteja presente no mesmo GameObject com:
[RequireComponent(typeof(Button))]
public class PopupOpener : MonoBehaviour
{
...
}
A primeira iteração do loop while (denotada pelo texto "ITERATION ON Button Invite (clone)") tentou excluir a Buttonprimeira, mas não pôde, pois depende do PopupOpenercomponente. isso gerou um erro. Em seguida, tentou excluir o PopupOpenercomponente, o que foi feito, pois não é dependente de mais nada. Na próxima iteração (indicada pelo segundo texto "ITERATION ON Button Invite (clone)"), ele tentou excluir o Buttoncomponente restante , o que agora poderia fazer, pois PopupOpenerfoi excluído na primeira iteração (após o erro).
Portanto, minha pergunta é se é possível verificar antecipadamente se um componente especificado pode ser removido de sua corrente GameObject, sem chamar Destroy()ou DestroyImmediate(). Obrigado.
Destroyremove o componente no final do quadro (ao contrário de Immediately). DestroyImmediateé considerado um estilo ruim, mas acho que mudar para Destroypode realmente eliminar esses erros.
