2017-02-22 44 views
3

我正在製作一個自定義編輯器,使用兩個GUI按鈕來實例化和銷燬多個對象。在編輯模式下,一切工作正常,我可以實例化多個預製件,然後從最後實例化到第一個,逐個銷燬它們,但只要按「播放」和「停止」,我就無法銷燬任何先前實例化的預製(在播放模式之前實例化)。我可以實例化新的預製件,然後銷燬它們,但對於那些在我玩遊戲之前實例化的預製件 - 它們不受影響。自定義編輯器在播放後重置?

現在,我並不太擔心這種情況發生在播放模式中,但我絕對想在播放模式之前繼續播放。

每當一個預製件被實例化時,我將它添加到一個堆棧並保持一個跟蹤的大小。在我玩遊戲 - 停止後,它似乎重置爲0.

在瀏覽了大量有關類似問題的帖子並檢查Unity的API之後,我意識到我需要找出一種方法來保存自定義編輯器設置和變量的序列化他們或使他們骯髒,我只是不知道如何做到這一點。我嘗試了這些帖子中的建議,但似乎沒有任何工作在我的情況下(或者我做錯了什麼)。

我有一個Monobehaviour腳本和一個編輯器腳本。我將發佈單個類型的對象的片段,因爲其他部分是相同的。

這是第一個:

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

[System.Serializable, ExecuteInEditMode] 
    public class ObjectControl: MonoBehaviour { 

[SerializeField, HideInInspector] 
public Stack<GameObject> undoStack = new Stack<GameObject>(); 
public GameObject instance; 
public int undoStackSize; 
public int objectSelectionIndex = 0; 

public void placeObject() 
{ 
    switch (objectSelectionIndex) 
    { 
     case 1: 

      Debug.Log("Just received a number 1 from the editor"); 
      GameObject object_A = Resources.Load("Prefabs/Object_A") as GameObject; 
      instance = Instantiate(object_A, this.transform.position, this.transform.rotation, this.transform); 

      undoStack.Push(instance); 
      undoStackSize = undoStack.Count; 

      break; 

     case 4: 

      Debug.Log("Just received a number 4 from the editor, deleting the object"); 

      if (undoStack.Count > 0) 
      { 
       GameObject objToUndo = undoStack.Pop(); 
       DestroyImmediate(objToUndo); 
       undoStackSize--; 

      } 

      else 
      { 
       Debug.Log("Stack is empty! Stack size is: " + undoStack.Count); 
      } 

      break; 
    } 
} 

和編輯器腳本:

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


[CustomEditor(typeof(ObjectControl)), CanEditMultipleObjects] 
public class ObjectControlEditor : Editor 
{ 

int objectSelectionToolbar = 0; 
int numberOfPossibleUndo; 

bool chooseOption = false; 
bool objectSelectionFoldout = false; 

public ObjectControl scriptTarget; 

public void Awake() 
{ 
    scriptTarget = (ObjectControl)target; 
} 

public override void OnInspectorGUI() 
{ 
    DrawDefaultInspector(); 

    GUI.changed = false; 

    chooseOption = EditorGUILayout.Foldout(chooseOption, "Choose a segment to add:"); 

    if (chooseOption) 
    { 

     EditorGUILayout.BeginVertical(); 

     stationSelectionFoldout = GUILayout.Toggle(stationSelectionFoldout, "" + (stationSelectionFoldout ? "▼ Object selection ▼" : "► Object selection ◄"), "Button", GUILayout.MaxWidth(Screen.width), GUILayout.Height(25)); 

     if (objectSelectionFoldout) 
     { 

      GUILayout.Space(5);  //Space before a text box 
      GUILayout.Box("Select lenght of the station:"); 
      GUILayout.Space(5);  //Space after a text box and before a toolbox 

      string[] objectSelectionToolbarOptions = new string[] { "Object A", "Object B", "Object C" }; 

      stationSelectionToolbar = GUILayout.Toolbar(objectSelectionToolbar, objectSelectionToolbarOptions, GUILayout.MinWidth(Screen.width), GUILayout.Height(50)); 
      GUILayout.Space(5); 

      RollerCoasterBuilder scriptTarget = (RollerCoasterBuilder)target; 
      numberOfPossibleUndo = scriptTarget.undoStackSize; 

      switch (objectSelectionToolbar) 
      { 
       case 0: 

        GUILayout.BeginHorizontal(); 

        if (GUILayout.Button("Place selected object", GUILayout.Height(30))) 
        { 
         scriptTarget.objectSelectionIndex = 1; 
         scriptTarget.PlaceObject(); 
        } 

        GUILayout.Space(5); 

        if (GUILayout.Button("Undo" + "(" + numberOfPossibleUndo + ")", GUILayout.Height(30))) 
        { 
         scriptTarget.objectSelectionIndex = 4; 
         scriptTarget.PlaceObject(); 
        } 

        GUILayout.EndHorizontal(); 

        break; 
       } 
      } 
     } 
    if (GUI.changed) 
     { 
     EditorUtility.SetDirty(target); 
     } 
} 
} 
+0

不要編輯您的初始文章並添加[解決]。這不是stackoverflow的工作原理。你應該把最好的標記作爲被接受的答案,或者做出自己的最佳答案。如果你放棄了這個問題並且沒有好的答案,你應該刪除這個問題。 – JHBonarius

+0

謝謝J.H.Bonarius,下次會做。 –

回答

1

團結不能序列化堆棧的數據類型。嘗試將您的undoStack轉換爲Array []或List <>。您可以在此處看到可序列化類型的列表:https://docs.unity3d.com/ScriptReference/SerializeField.html

或者,如果Unity尚不支持它,則可以編寫自己的可序列化版本的類型。見:http://answers.unity3d.com/questions/460727/how-to-serialize-dictionary-with-unity-serializati.html(第二回復)。

此外,請務必閱讀API中EditorUtility.SetDirty()頁面的NOTE部分,以確保您的當前實現不針對Unity的穀物運行。我無法鏈接它,因爲我只有足夠的代表發佈2鏈接...

0

感謝邁克爾的輸入。

我已經決定放棄堆棧,除去所子對象進行的,一個接一個,從後到前,如能在這個帖子中可以看出:後播放模式Simple way to Delete the Last Child of a GameObject

沒有更多的問題: )

祝您有美好的一天!