Ich entwickle ein Spiel in Unity und nutze es liberal, [RequireComponent(typeof(%ComponentType%))]
um sicherzustellen, dass die Komponenten alle Abhängigkeiten erfüllen.
Ich implementiere jetzt ein Tutorial-System, das verschiedene UI-Objekte hervorhebt. Um die Hervorhebung durchzuführen, verweise ich auf die GameObject
in der Szene, klone sie dann mit Instantiate () und entferne rekursiv alle Komponenten, die für die Anzeige nicht benötigt werden. Das Problem ist, dass bei der liberalen Verwendung RequireComponent
dieser Komponenten viele nicht einfach in beliebiger Reihenfolge entfernt werden können, da sie von anderen Komponenten abhängen, die noch nicht gelöscht wurden.
Meine Frage ist: Gibt es eine Möglichkeit festzustellen, ob ein Component
aus dem GameObject
aktuell angehängten entfernt werden kann?
Der Code, den ich veröffentliche, funktioniert technisch, löst jedoch Unity-Fehler aus (nicht im Try-Catch-Block abgefangen, wie im Bild dargestellt)
Hier ist der Code:
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);
}
}
Die Art und Weise, wie dieser Code die letzten drei Zeilen des obigen Debug-Protokolls generiert hat, ist die folgende: Als Eingabe wurde a GameObject
mit zwei Komponenten verwendet: Button
und PopupOpener
. PopupOpener
erfordert, dass eine Button
Komponente in demselben GameObject vorhanden ist mit:
[RequireComponent(typeof(Button))]
public class PopupOpener : MonoBehaviour
{
...
}
Bei der ersten Iteration der while-Schleife (gekennzeichnet durch den Text "ITERATION ON Button Invite (Klon)") wurde versucht, die Button
erste zu löschen , dies konnte jedoch nicht, da dies von der PopupOpener
Komponente abhängt . Dies warf einen Fehler. Dann wurde versucht, die PopupOpener
Komponente zu löschen , was auch der Fall war, da sie von nichts anderem abhängig ist. In der nächsten Iteration (gekennzeichnet durch den zweiten Text "ITERATION ON Button Invite (Klon)") wurde versucht, die verbleibende Button
Komponente zu löschen , was jetzt möglich war, da PopupOpener
sie in der ersten Iteration (nach dem Fehler) gelöscht wurde.
Meine Frage ist also, ob es möglich ist, im Voraus zu prüfen, ob eine bestimmte Komponente aus ihrer aktuellen entfernt werden kann GameObject
, ohne Destroy()
oder aufzurufen DestroyImmediate()
. Vielen Dank.
Destroy
entferne aber die Komponente am Ende des Rahmens (im Gegensatz zu Immediate
ly). DestroyImmediate
wird sowieso als schlechter Stil angesehen, aber ich denke, ein Wechsel zu Destroy
kann diese Fehler tatsächlich beseitigen.