using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
[CustomEditor(typeof(ConversationTrigger))]
public class ConversationTriggerEditor : Editor
{
private Vector2 scrollPos;
private SerializedProperty conversations;
private ConversationTrigger conversationTrigger;
private ReorderableList conversationList;
private void OnEnable()
{
conversations = serializedObject.FindProperty("conversations");
conversationTrigger = (ConversationTrigger)target;
conversationList = new ReorderableList(serializedObject, conversations)
{
displayAdd = true,
displayRemove = true,
draggable = true,
onAddCallback = addcallback =>
{
addcallback.list[addcallback.list.Count] = default;
},
drawElementCallback = (rect, index, isActive, isSelected) =>
{
var element = conversations.GetArrayElementAtIndex(index);
var name = element.FindPropertyRelative("Name");
// do this for all properties
var position = EditorGUI.PrefixLabel(rect, new GUIContent(name.stringValue));
EditorGUI.PropertyField(position, name);
},
elementHeight = EditorGUIUtility.singleLineHeight
};
}
public override void OnInspectorGUI()
{
// Load the current values from the real component into the serialized copy
serializedObject.Update();
EditorGUILayout.LabelField("Conversations", EditorStyles.boldLabel);
var newSize = EditorGUILayout.IntField(conversations.arraySize);
conversations.arraySize = Mathf.Max(0, newSize);
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Height(250));
GUILayout.Space(10);
conversationList.DoLayoutList();
EditorGUILayout.EndScrollView();
if (GUILayout.Button("Add new conversation"))
{
conversations.arraySize++;
}
GUILayout.Space(10);
if (conversations.arraySize != 0)
{
if (GUILayout.Button("Remove conversation"))
{
if (conversations.arraySize > 0) conversations.arraySize--;
}
}
GUILayout.Space(100);
if (GUILayout.Button("Save Conversations"))
{
conversationTrigger.SaveConversations();
}
GUILayout.Space(10);
if (GUILayout.Button("Load Conversations"))
{
Undo.RecordObject(conversationTrigger, "Loaded conversations from JSON");
conversationTrigger.LoadConversations();
}
serializedObject.ApplyModifiedProperties();
}
}
主要有两个问题:
首先:属性displayAdd和displayRemove必须为true才能使用onAddCallback。也许只有displayAdd必须为true。如果它是错误的,我使用了一个断点,它永远不会到达终点:
addcallback.list[addcallback.list.Count] = default;
如果都为true,则转到此行,但想法是将最新添加的项目设置为ReorderableList,使其默认为空而没有名称,因为现在添加新的对话时,它会复制最后一个项目。相反,我想添加一个新的空项目。
第二条:即使到达该行,该行也无法正常工作,它一直无济于事,不断添加重复项:
addcallback.list[addcallback.list.Count] = default;
当displayAdd和displayRemove均为false时,如何使用onAddCallback?我希望它们是假的,因为我在伪造使用两个按钮的添加/删除。 但是,如果它们为假,则无法使用onAddCallback
以及如何设置和添加新项目时将其命名为空?
答案 0 :(得分:1)
一旦覆盖onAddCallback
,就必须积极增加arraySize
,如果不覆盖它,这是默认行为。
// you don't have to go through the list property
// you could ofcourse but anyway you already know which list
// you want to change
onAddCallback = list =>
{
// first add one element
conversations.arraySize++;
// then get that element
var newIndex = conversations.arraySize - 1;
var newElement = conversations.GetArrayElementAtIndex(newIndex);
// now reset all properties like
var name = newElement.FindPropertyRelative("Name");
name.stringValue = "";
// ...
},
请注意,这无法与您的
一起使用GUILayout.Button("Add new conversation")
也不通过
添加新元素EditorGUILayout.IntField(conversations.arraySize);
首先,您可以简单地像
if(GUILayout.Button("Add new conversation"))
{
// first add one element
conversations.arraySize++;
// then get that element
var newIndex = conversations.arraySize - 1;
var newElement = conversations.GetArrayElementAtIndex(newIndex);
// now reset all properties like
var name = newElement.FindPropertyRelative("Name");
name.stringValue = "";
}
第二秒钟,您必须检查是否删除了元素或添加了元素以及数量:
EditorGUI.BeginChangeCheck();
{
var newSize = EditorGUILayout.IntField(conversations.arraySize);
}
if(EditorGUI.EndChangeCheck())
{
if(newSize > conversations.arraySize)
{
// elements have to be added -> how many?
var toAdd = newSize - conversations.arraySize - 1;
// why -1 ? -> We add the first element and set its values to default
// now if we simply increase the arraySize for the rest of the elements
// they will be all a copy of the first -> all defaults ;)
// first add one element
conversations.arraySize++;
// then get that element
var newIndex = conversations.arraySize - 1;
var newElement = conversations.GetArrayElementAtIndex(newIndex);
// now reset all properties like
var name = newElement.FindPropertyRelative("Name");
name.stringValue = "";
// now for the rest simply increase arraySize
conversations.arraySize += toAdd;
}
else
{
// for removing just make sure the arraySize is not under 0
conversations.arraySize = Mathf.Max(newSize, 0);
}
}
不幸的是,Unity EditorScripting就是这样。直到现在,它仍然很糟糕并且变得非常复杂,只是为了获得所需的布局;)
但是他们正在努力,新的alpha和beta版本2019.2和2019.3已经提供了新的Inspector和Unity GUI的一些预览,并且可能会有更简单的方法来进行编辑器设计...;)