using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
[CustomEditor(typeof(ConversationTrigger))]
public class ConversationTriggerEditor : Editor
{
public ConversationsEditorWindow initser()
{
ConversationsEditorWindow myWindow = CreateInstance<ConversationsEditorWindow>();
//myWindow.Init(serializedObject);
SerializedObject serobject = new SerializedObject(myWindow);
myWindow.Init(serobject);
return myWindow;
}
public override void OnInspectorGUI()
{
if (GUILayout.Button("Configure Item"))
{
ConversationsEditorWindow myWindow = CreateInstance<ConversationsEditorWindow>();
//myWindow.Init(serializedObject);
myWindow.Init(serializedObject);
}
}
}
第一次使用OnInspectorGUI中的按钮,它在该按钮上工作正常。但是现在我不希望在“编辑器”脚本中使用按钮,而是在“编辑器窗口”脚本中使用项目菜单。
所以我在编辑器脚本中创建了一个称为initser的方法。
然后在编辑器窗口中:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
public class ConversationsEditorWindow : EditorWindow
{
public static SerializedObject conversation = null;
private static ConversationTrigger _conversationTrigger;
[SerializeField] private static ReorderableList conversationsList;
private static SerializedProperty _conversations;
private static int _currentlySelectedConversationIndex = -1;
private static int newSize = 0;
private static Vector2 scrollPos;
private readonly static Dictionary<string, ReorderableList> _dialoguesListDict = new Dictionary<string, ReorderableList>();
private readonly static Dictionary<string, ReorderableList> _sentencesListDict = new Dictionary<string, ReorderableList>();
private static SerializedObject itemcopy;
[MenuItem("Dialog System/Conversations")]
private static void ConversationsWindow()
{
const int width = 800;
const int height = 800;
var x = (Screen.currentResolution.width - width) / 2;
var y = (Screen.currentResolution.height - height) / 2;
var window = GetWindow<ConversationsEditorWindow>();
window.position = new Rect(x, y, width, height);
ConversationTriggerEditor triggereditor = new ConversationTriggerEditor();
triggereditor.initser();
}
public void Init(SerializedObject _item)
{
// Copy the Item targetObject to not lose reference when you
// click another element on the project window.
itemcopy = new SerializedObject(_item.targetObject);
conversation = itemcopy;
// Other things to initialize the window
_conversationTrigger = (ConversationTrigger)_item.targetObject;
_conversations = itemcopy.FindProperty("conversations");
conversationsList = new ReorderableList(itemcopy, _conversations)
{
displayAdd = true,
displayRemove = true,
draggable = true,
drawHeaderCallback = DrawConversationsHeader,
drawElementCallback = DrawConversationsElement,
onAddCallback = (list) =>
{
SerializedProperty addedElement;
// if something is selected add after that element otherwise on the end
if (_currentlySelectedConversationIndex >= 0)
{
list.serializedProperty.InsertArrayElementAtIndex(_currentlySelectedConversationIndex + 1);
addedElement = list.serializedProperty.GetArrayElementAtIndex(_currentlySelectedConversationIndex + 1);
}
else
{
list.serializedProperty.arraySize++;
addedElement = list.serializedProperty.GetArrayElementAtIndex(list.serializedProperty.arraySize - 1);
}
var name = addedElement.FindPropertyRelative("Name");
var foldout = addedElement.FindPropertyRelative("Foldout");
var dialogues = addedElement.FindPropertyRelative("Dialogues");
name.stringValue = "";
foldout.boolValue = false;
dialogues.arraySize = 0;
},
elementHeightCallback = (index) =>
{
return GetConversationHeight(_conversations.GetArrayElementAtIndex(index));
}
};
}
private void OnGUI()
{
if (itemcopy != null)
{
itemcopy.Update();
// if there are no elements reset _currentlySelectedConversationIndex
if (conversationsList.serializedProperty.arraySize - 1 < _currentlySelectedConversationIndex) _currentlySelectedConversationIndex = -1;
现在对话列表为空。
在此之前,当我在“编辑器”脚本中使用按钮时,我在这里使用菜单项而不是使其静态化:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
public class ConversationsEditorWindow : EditorWindow
{
public static SerializedObject conversation = null;
private static ConversationTrigger _conversationTrigger;
[SerializeField] private static ReorderableList conversationsList;
private static SerializedProperty _conversations;
private static int _currentlySelectedConversationIndex = -1;
private static int newSize = 0;
private static Vector2 scrollPos;
private readonly static Dictionary<string, ReorderableList> _dialoguesListDict = new Dictionary<string, ReorderableList>();
private readonly static Dictionary<string, ReorderableList> _sentencesListDict = new Dictionary<string, ReorderableList>();
private static SerializedObject itemcopy;
public void Init(SerializedObject _item)
{
// Copy the Item targetObject to not lose reference when you
// click another element on the project window.
itemcopy = new SerializedObject(_item.targetObject);
conversation = itemcopy;
// Other things to initialize the window
const int width = 800;
const int height = 800;
var x = (Screen.currentResolution.width - width) / 2;
var y = (Screen.currentResolution.height - height) / 2;
var window = GetWindow<ConversationsEditorWindow>();
window.position = new Rect(x, y, width, height);
_conversationTrigger = (ConversationTrigger)_item.targetObject;
_conversations = itemcopy.FindProperty("conversations");
conversationsList = new ReorderableList(itemcopy, _conversations)
{
displayAdd = true,
displayRemove = true,
draggable = true,
drawHeaderCallback = DrawConversationsHeader,
drawElementCallback = DrawConversationsElement,
onAddCallback = (list) =>
{
SerializedProperty addedElement;
// if something is selected add after that element otherwise on the end
if (_currentlySelectedConversationIndex >= 0)
{
list.serializedProperty.InsertArrayElementAtIndex(_currentlySelectedConversationIndex + 1);
addedElement = list.serializedProperty.GetArrayElementAtIndex(_currentlySelectedConversationIndex + 1);
}
else
{
list.serializedProperty.arraySize++;
addedElement = list.serializedProperty.GetArrayElementAtIndex(list.serializedProperty.arraySize - 1);
}
var name = addedElement.FindPropertyRelative("Name");
var foldout = addedElement.FindPropertyRelative("Foldout");
var dialogues = addedElement.FindPropertyRelative("Dialogues");
name.stringValue = "";
foldout.boolValue = false;
dialogues.arraySize = 0;
},
elementHeightCallback = (index) =>
{
return GetConversationHeight(_conversations.GetArrayElementAtIndex(index));
}
};
}
最后,我要做的是将序列化对象从编辑器脚本传递到编辑器窗口脚本,而在编辑器脚本中没有按钮。
答案 0 :(得分:1)
您不想像在SerializedObject
中那样创建EditorWindow
实例的serobject = new SerializedObject(myWindow);
,而是传递编辑脚本的serializedObject
引用。< / p>
主要问题:您不能简单地使用
ConversationTriggerEditor triggereditor = new ConversationTriggerEditor();
这没有任何意义。一旦相应的ConversationTriggerEditor
实例获得焦点并加载了检查器,则ConversationTrigger
实例将由Unity内部创建。如果您使用new
创建实例,那么该ConversationTriggerEditor
实例应该如何知道它属于哪个实际ConversationTrigger
组件?
相反,您必须以某种方式获取相应的ConversationTrigger
实例的引用,例如使用
var conversationTrigger = FindObjectOfType<ConversationTrigger>();
,然后使用
从中创建SerializedObject
var conversationTriggerSerializedObject = new SerializedObject(conversationTrigger);
请注意,将conversationTriggerSerializedObject
的所有更改也都包含在其中
conversationTriggerSerializedObject.Update();
// ...
conversationTriggerSerializedObject.ApplyModifiedProperties();