如何在编辑器中显示和修改数组Window?
How to display & modify array in the Editor Window?
我的 CustomEditor class 中有 GameObject 数组字段,派生自 UnityEngine.Editor。我需要能够显示(绘制)并让用户能够修改该数组。
就像 Unity 的 Inspector 对从 ScriptableObject 派生的对象的可序列化字段执行此操作一样。例如。在检查器中显示材料数组:
public GameObject[] yourGameObjects;
然后在检查器中设置您的大小,然后应该会打开字段。
向您的脚本添加一个 public 数组
public GameObject[] myObjects
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.
我设法用一个 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;
}
}
}
最佳答案对我来说效果不佳,因为属性没有更新,因此我将声明行移到了 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
}
}
链接:
我的 CustomEditor class 中有 GameObject 数组字段,派生自 UnityEngine.Editor。我需要能够显示(绘制)并让用户能够修改该数组。
就像 Unity 的 Inspector 对从 ScriptableObject 派生的对象的可序列化字段执行此操作一样。例如。在检查器中显示材料数组:
public GameObject[] yourGameObjects;
然后在检查器中设置您的大小,然后应该会打开字段。
向您的脚本添加一个 public 数组
public GameObject[] myObjects
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.
我设法用一个 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;
}
}
}
最佳答案对我来说效果不佳,因为属性没有更新,因此我将声明行移到了 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
}
}
链接: