我正在尝试在检查器中绘制列表项,但无法正常工作,如何用自己的字符串替换element0,element1 ....?
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(PickupObjects))]
public class PickupObjectsEditor : Editor
{
private static List<GameObject> pickeditems = new List<GameObject>();
private static bool picked = false;
private SerializedProperty _serializedpickeditems;
[MenuItem("GameObject/Generate as Pickup Item", false, 30)]
public static void GeneratePickupItems()
{
if (Selection.gameObjects.Length > 0)
{
for (int i = 0; i < Selection.gameObjects.Length; i++)
{
if (Selection.gameObjects[i].GetComponent<TestScript>() == null)
{
Selection.gameObjects[i].AddComponent<BoxCollider>();
Selection.gameObjects[i].AddComponent<TestScript>();
}
Selection.gameObjects[i].layer = 9;
Selection.gameObjects[i].tag = "Pickup Item";
pickeditems.Add(Selection.gameObjects[i]);
}
picked = true;
}
}
public override void OnInspectorGUI()
{
serializedObject.Update();
PickupObjects myTarget = (PickupObjects)target;
DrawDefaultInspector();
if (picked == true)
{
for (int i = 0; i < pickeditems.Count; i++)
{
myTarget.pickUpObjects.Add(pickeditems[i]);
var item = _serializedpickeditems.GetArrayElementAtIndex(i);
var serializedItem = new SerializedObject(item.objectReferenceValue);
serializedItem.Update();
EditorGUILayout.PropertyField(item, new GUIContent("Picked Item " + i + " " + item.name));
serializedItem.ApplyModifiedProperties();
}
pickeditems.Clear();
picked = false;
serializedObject.ApplyModifiedProperties();
}
}
private void OnEnable()
{
_serializedpickeditems = serializedObject.FindProperty("pickUpObjects");
}
}
和单声道脚本
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class PickupObjects : MonoBehaviour
{
public List<GameObject> pickUpObjects = new List<GameObject>();
}
我尝试使用serialize和PropertyField,但仍然显示带有Element0,Element1,Element2 ...的列表.我希望它是:
I tried to use serialize and PropertyField but still it's showing the List with Element0,Element1,Element2.... And I want it to be :
Picked Item Box
Picked Item Can
Picked Item Cube
Picked Item Dock_Pod
您的
EditorGUILayout.PropertyField(item, new GUIContent("Picked Item " + i + " " + item.name));
位于仅一次执行的代码块中.
sits within a code block that is only executed once.
您当前看到的内容实际上是仅由
What you see currently is actually only the list drawn by
DrawDefaultInspector();
因为其余的内容在1帧/绘制呼叫后消失了.
since the rest is disappeared after 1 frame/draw call.
例如,您希望将图形的方法"与图形分开.
You would rather want to separate the pick "method" from the drawing like e.g.
public override void OnInspectorGUI()
{
serializedObject.Update();
if (picked)
{
for (var i = 0; i < pickeditems.Count; i++)
{
// NOTE: Never mix serializedProperties and direct access/modifications on the target!
// This messes up the marking dirty and saving these changes!
// Rather always go through the SerializedProperties so the editor handles everything automatically
_serializedpickeditems.arraySize++;
_serializedpickeditems.GetArrayElementAtIndex(i).objectReferenceValue = pickeditems[i];
}
picked = false;
pickeditems.Clear();
}
for (var i = 0; i < _serializedpickeditems.arraySize; i++)
{
var item = _serializedpickeditems.GetArrayElementAtIndex(i);
// little bonus from me: Color the field if the value is null ;)
var color = GUI.color;
if(!item.objectReferenceValue) GUI.color = Color.red;
{
EditorGUILayout.PropertyField(item, new GUIContent("Picked Item " + i + " " + (item.objectReferenceValue ? item.objectReferenceValue.name : "null")));
}
GUI.color = color;
// The only case you would need to go deeper here and use
// your new SerializedObject would be if you actually make changes
// to these objects/components like e.g. directly allow to edit their name
}
serializedObject.ApplyModifiedProperties();
}
请注意,在添加新项目之前,您还应该清除pickeditems
列表:
Note you should also clear the pickeditems
list before adding new items:
[MenuItem("GameObject/Generate as Pickup Item", false, 30)]
public static void GeneratePickupItems()
{
if (Selection.gameObjects.Length > 0)
{
pickeditems.Clear();
for (int i = 0; i < Selection.gameObjects.Length; i++)
{
if (Selection.gameObjects[i].GetComponent<Whilefun.FPEKit.FPEInteractablePickupScript>() == null)
{
Selection.gameObjects[i].AddComponent<BoxCollider>();
Selection.gameObjects[i].AddComponent<Whilefun.FPEKit.FPEInteractablePickupScript>();
}
Selection.gameObjects[i].layer = 9;
Selection.gameObjects[i].tag = "Pickup Item";
pickeditems.Add(Selection.gameObjects[i]);
}
picked = true;
}
}
通常,我总是建议使用 ReorderableList
!
In general I always recommend to use a ReorderableList
!
一开始它有点棘手,但是一旦设置好它就是一个了不起的工具.即使您实际上无法将其重新排序,例如能够动态地从中间移除一个项目;)
It's a bit tricky at first to get into it but as soon as you have set it up it is an amazing tool. even if you don't make it actually reorderable it is still a huge advantage to be e.g. able to dynamically remove an item from the middle ;)