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

5
我在自定义编辑器类中继承了UnityEngine.Editor,有一个GameObject数组字段。我需要能够显示(绘制)并让用户修改该数组。 就像Unity的检查器为ScriptableObject派生的可序列化对象的字段所做的那样。例如,在检查器中显示材质数组: .
5个回答

10

将您的编辑器对象视为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
    }
}

原始答案在这里


当我在编辑器窗口中更改值时,值不会改变... 我认为这是so.ApplyModifiedProperties();行的问题,但我需要帮助解决。 - amitklein
好的,我已经找到了解决方案,我会在答案中进行编辑,但基本上你需要在 OnEnable() 中声明变量并使用 so.Update() 函数。 - amitklein
无法编辑,因此发布了另一个答案。 - amitklein

1

我使用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;
        }
    }
}

1

对我来说,最佳答案并不起作用,因为属性没有更新,所以我将声明行移动到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
    }
}

链接:

我的答案基础

SerializedObject.Update


-2

public GameObject[] yourGameObjects;

然后在检视面板中设置你的大小,字段应该会打开。


我指的是EditorWindow类。它允许您在IDE中创建自定义窗口。 - Ilya Mashin
@ИльяМашин,我不明白你的意思。Fribu提供的答案和这个都会显示像你提供的图片中的变量。 - Tom
这个类用于在编辑器模式下创建自定义窗口。我尝试添加一个游戏对象数组字段。 - Ilya Mashin
@ИльяМашин,你提供的链接似乎对于一个简单的公共GameObject数组来说有些过度杀伐了。 - Tom
我添加了那个链接以便你理解我想创建什么。我不需要在检视面板中有公共数组,我需要将数组添加到EditorWindow对象中,就像EditorGUILayout.ObjectField一样,但是是数组字段。 - Ilya Mashin

-2
在您的脚本中添加一个公共数组。
public GameObject[] myObjects

这在playmode中工作。我的意思是Editor scripting和EditorWindow。 - Ilya Mashin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接