Al desarrollar un juego en Unity, estoy haciendo un uso liberal [RequireComponent(typeof(%ComponentType%))]
para asegurar que los componentes tengan todas las dependencias satisfechas.
Ahora estoy implementando un sistema tutorial que destaca varios objetos de la interfaz de usuario. Para resaltar, tomo una referencia a la GameObject
escena, luego la clono con Instantiate () y luego elimino recursivamente todos los componentes que no son necesarios para mostrar. El problema es que con el uso liberal de RequireComponent
estos componentes, muchos no pueden eliminarse simplemente en cualquier orden, ya que dependen de otros componentes que aún no se han eliminado.
Mi pregunta es: ¿Hay alguna manera de determinar si Component
se puede eliminar un archivo al GameObject
que está conectado actualmente?
El código que estoy publicando técnicamente funciona, sin embargo, arroja errores de Unity (no atrapados en el bloque try-catch, como se ve en la imagen
Aquí está el 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);
}
}
Entonces, la forma en que este código generó las últimas tres líneas del registro de depuración anterior es la siguiente: tomó como entrada a GameObject
con dos componentes: Button
y PopupOpener
. PopupOpener
requiere que un Button
componente esté presente en el mismo GameObject con:
[RequireComponent(typeof(Button))]
public class PopupOpener : MonoBehaviour
{
...
}
La primera iteración del bucle while (denotado por el texto "ITERATION ON Button Invite (clone)") intentó eliminar el Button
primero, pero no pudo, ya que depende del PopupOpener
componente. Esto arrojó un error. Luego intentó eliminar el PopupOpener
componente, lo que hizo, ya que no depende de nada más. En la siguiente iteración (Denotado por el segundo texto "ITERATION ON Button Invite (clone)"), intentó eliminar el Button
componente restante , lo que ahora podría hacer, ya que PopupOpener
se eliminó en la primera iteración (después del error).
Entonces, mi pregunta es si es posible verificar con anticipación si un componente específico se puede eliminar de su actual GameObject
, sin invocar Destroy()
o DestroyImmediate()
. Gracias.
Destroy
elimina el componente al final del marco (en lugar de Immediate
ly). DestroyImmediate
De todos modos, se considera un mal estilo, pero estoy pensando que cambiar Destroy
podría eliminar estos errores.