2016-11-15 3 views
1

Ich habe einen Unity-Code, der ein Gitter (insgesamt 2^Dimensionen) eines Prefab mit einem C# -Skript erstellt. Nachdem ich den Wert für "Dimensionen" geändert habe (vorerst über den Editor), würde ich gerne sehen, dass alle Prefabs gelöscht werden, bevor Unity mit OnValidate aktualisiert wird. Unity scheint die vorherige Gruppe von Objekten, die den Bereich darstellen, nicht löschen zu wollen, da diese Objekte weiterhin im Unity-Hierarchy-Fensterbereich verfügbar sind: Probleme beim Zerstören von Objekten in der Einheit. der Fehler sagt:Kann die Transformationskomponente des Fehlers nicht zerstören

"Can't destroy Transform component of 'XXX'. If you want to destroy the game object, please call 'Destroy' on the game object instead. Destroying the transform component is not allowed."

(siehe DeletePoints/GeneratePoints funktionieren Graph Aufruf:. OnValidate -> GeneratePoints (-> DeletePoints, -> GeneratePointsHelper)

using UnityEngine; 
using System; 
using System.Collections.Generic; 
using System.Collections; 

public class BinarySpacePointGenerator : MonoBehaviour { 
    private const int UNITY_DRAW_SPACE_DIMENSIONALITY = 3; 
    /** 
    * These values denote spacings for the three dimensional space between binary points. 
    */ 
    public float xoff, yoff, zoff; 
    public float scale; 
    public Transform pointPrefab; 
    /** 
    * The current dimensionality of binary space to be displayed. 
    */ 
    public int dimensions; 

    /* 
    * The container of points that represent our B space. 
    */ 
    private List<Transform> points; 

    // Use this for initialization 
    void Start() { 
     xoff = 1.0f; 
     yoff = 1.0f; 
     zoff = 1.0f; 
     scale = 0.25f; 
     dimensions = 2; 
     points = new List<Transform>(); 
     GeneratePoints(); 
    } 

    void OnValidate() { 
     /* ensure dimensionality */ 
     /* TODO: set up a B^0 space. */ 
     if (dimensions < 1) { 
      dimensions = 1; 
     } 
     if (dimensions >= 13) { 
      dimensions = 12; 
     } 
     /* ensure that our spacing sizes are valid */ 
     if (xoff <= 0.0f) { 
      xoff = 1.0f; 
     } 
     if (yoff <= 0.0f) { 
      yoff = 1.0f; 
     } 
     if (zoff <= 0.0f) { 
      zoff = 1.0f; 
     } 
     if (scale <= 0.0f) { 
      scale = 0.25f; 
     } 

     /* now that we've ensured the dimensionality, we can change the space */ 
     GeneratePoints(); 
    } 

    private void DeletePoints() { 
     for (int i = 0; i < transform.childCount; i++) { 
      Destroy (transform.GetChild (0)); 
     } 
     points.RemoveRange(0, points.Count); /* pop off */ 
    } 

    /** 
    * Instantiates the points field based on the value of dimensions at call-time. 
    */ 
    private void GeneratePoints() { 
     DeletePoints(); 

     int[] vectorProto = new int[dimensions]; 
     for (int i = 0; i < dimensions; i++) { 
      vectorProto [i] = 0; 

     } 
     GeneratePointsHelper(vectorProto, dimensions); 
    } 

    /** 
    * 
    * GeneratePointsHelper 
    * 
    * Description: Recursively builds the binary space B^n. 
    * 
    * Parameters: 
    *  int[] vector: the proto-type of all higher dimensions for the current trail. 
    *  int  n: the number of dimensions left to traverse from this recursion step. 
    * 
    * Recursion Termination/Description: 
    *  When n == 0, which means that we have created a unique vector. 
    * 
    */ 
    private void GeneratePointsHelper(int[] vector, int n) { 
     if (n == 0) { 
      // use vector to set Sphere object 
      var point = Instantiate(pointPrefab); 
      Vector3 pointPosition = new Vector3(); 
      pointPosition.x = 0; 
      pointPosition.y = 0; 
      pointPosition.z = 0; 
      for (int i = 0; i < dimensions; i++) { 

       int d = (i/UNITY_DRAW_SPACE_DIMENSIONALITY); 

       if (i % UNITY_DRAW_SPACE_DIMENSIONALITY == 0) { 
        pointPosition.x += (xoff * vector[i] * Mathf.Pow(2, d)); 
       } else if (i % UNITY_DRAW_SPACE_DIMENSIONALITY == 1) { 
        pointPosition.y += (yoff * vector[i] * Mathf.Pow(2, d)); 
       } else if (i % UNITY_DRAW_SPACE_DIMENSIONALITY == 2) { 
        pointPosition.z += (zoff * vector[i] * Mathf.Pow(2, d)); 
       } 
      } 
      point.localPosition = pointPosition; 
      point.localScale = new Vector3 (scale, scale, scale); 
      point.parent = transform; 
      points.Add (point); 

     } else { 
      vector[dimensions-n] = 0; 
      GeneratePointsHelper (vector, n - 1); 

      vector[dimensions-n] = 1; 
      GeneratePointsHelper (vector, n - 1); 
     } 
    } 
} 
+1

Dieser Thread scheint über das gleiche Problem zu sprechen: https://forum.unity3d.com/threads/onvalidate-and-destroying-objects.258782/ – CaTs

Antwort

4

Sie zerstören derzeit die Gameobjects mit . Destroy (transform.GetChild (0));

Das Problem ist, dass transform.GetChild ein Transform zurückgibt und Sie Transform nicht zerstören können mit der neuesten Version der Einheit, werden Sie diese Fehlermeldung erhalten:.

Can't destroy Transform component of 'GameObject'. If you want to destroy the game object, please call 'Destroy' on the game object instead. Destroying the transform component is not allowed.

Sie müssen das GameObject von der Transform zugreifen und dann zerstören. Sie müssen auch i in GetChild anstelle von 0 verwenden, da Destroy in der for-Schleife aufgerufen wird, und das ist wahrscheinlich, was Sie versuchen zu tun.

for (int i = 0; i < transform.childCount; i++) 
{ 
    Destroy(transform.GetChild(i).gameObject); 
} 

I'd like to see all the prefabs get deleted, before Unity updates using OnValidate

nennen Dann DeletePoints() in der ersten Zeile der void OnValidate(){} Funktion.

+0

"Ich möchte alle Prefabs gelöscht werden sehen" Darauf solltest du dich bei diesem Problem wirklich konzentrieren. Es handelt sich vielmehr um das Problem, dass die Unity-API zur Verwaltung von GameObjects missbraucht wird. Von dem, was ich verstehe, scheint es wirklich nicht wie relative Platzierung der Destroy (Kind) Schleife (ob ich diesen Loop-Code in "OnValidate" oder in einer Funktion, die "OnValidate" untergeordnet ist platziert). Ich denke, was letztendlich passiert ist, dass ich meine Destroy (Child) -Schleife falsch "gekocht" habe, indem ich die falschen Objekte/Funktionen benutzt habe. Wenn das falsch ist, korrigieren Sie bitte mein Verständnis :) – Ian

Verwandte Themen