代码之家  ›  专栏  ›  技术社区  ›  Iliya Mashin

如何在编辑器窗口中显示和修改数组?

  •  4
  • Iliya Mashin  · 技术社区  · 6 年前

    我在从UnityEngine派生的CustomEditor类中有GameObject数组字段。编辑我需要能够显示(绘制)并允许用户修改该数组。

    就像Unity的Inspector如何对从ScriptableObject派生的对象的可序列化字段执行此操作一样。E、 g.在检查器中显示材质数组: .

    5 回复  |  直到 6 年前
        1
  •  8
  •   marc_s    2 年前

    参考您的编辑器对象作为SerializedObject,然后找到任何必需的属性,绘制它,并应用修改:

    public class MyEditorWindow : EditorWindow
    {
        [MenuItem("Window/My Editor Window")]
        public static void ShowWindow()
        {
            GetWindow<MyEditorWindow>();
        }
    
        public string[] Strings = { "Larry", "Curly", "Moe" };
    
        void OnGUI()
        {
            // "target" can be any class derived from ScriptableObject 
            // (could be EditorWindow, MonoBehaviour, etc)
            ScriptableObject target = this;
            SerializedObject so = new SerializedObject(target);
            SerializedProperty stringsProperty = so.FindProperty("Strings");
    
            EditorGUILayout.PropertyField(stringsProperty, true); // True means show children
            so.ApplyModifiedProperties(); // Remember to apply modified properties
        }
    }
    

    原始答案 here .

        2
  •  1
  •   santaclos    4 年前

    我用for循环和额外的int实现了这一点:

    using UnityEditor;
    using UnityEngine;
    
    public class RockSpawner : EditorWindow
    {
        int rockCollectionSize = 0;
        GameObject[] rockCollection;
    
        [MenuItem("Tools/Rock Spawner")]
        public static void ShowWindow()
        {
            GetWindow(typeof(RockSpawner));
        }
    
        void OnGUI()
        {
            rockCollectionSize = EditorGUILayout.IntField("Rock collection size", rockCollectionSize);
            if (rockCollection != null && rockCollectionSize != rockCollection.Length)
                rockCollection = new GameObject[rockCollectionSize];
            for (int i = 0; i < rockCollectionSize; i++)
            {
                rockCollection[i] = EditorGUILayout.ObjectField("Rock " + i.ToString(), rockCollection[i], typeof(GameObject), false) as GameObject;
            }
        }
    }
    
        3
  •  0
  •   marc_s    2 年前

    顶部的答案对我来说不太合适,因为属性没有更新,因为我将声明行移到了 OnEnable 不想反复声明的函数)并用于 so.Update() 更新更改的变量。

    using UnityEngine;
    using UnityEditor;
    
    public class MyEditorWindow : EditorWindow
    {
        [MenuItem("Window/My Editor Window")]
        public static void ShowWindow()
        {
            GetWindow<MyEditorWindow>();
        }
    
        public string[] Strings = { "Larry", "Curly", "Moe" };
        SerializedObject so;
    
        private void OnEnable()
        {
            ScriptableObject target = this;
            so = new SerializedObject(target);
        }
    
        void OnGUI()
        {
            // "target" can be any class derived from ScriptableObject 
            // (could be EditorWindow, MonoBehaviour, etc)
            so.Update();
            SerializedProperty stringsProperty = so.FindProperty("Strings");
    
            EditorGUILayout.PropertyField(stringsProperty, true); // True means show children
            so.ApplyModifiedProperties(); // Remember to apply modified properties
        }
    }
    

    链接:

    Base for my answer

    SerializedObject.Update

        4
  •  -1
  •   Tom    6 年前

    public GameObject[] yourGameObjects;

    然后在inspector中设置您的大小,字段应打开。

        5
  •  -2
  •   Alexander_F    6 年前

    将公共数组添加到脚本中

    public GameObject[] myObjects