C# 如何在编辑器窗口中以相同的大小显示Inspector窗口?
问题是,在Inspector中,它看起来很好,正如我所希望的,但在编辑器窗口中,控件和字段不在相同的位置 在屏幕截图中,检查器窗口位于右侧,编辑器窗口位于左侧。问题在于Inspector上的对话名称“名称”字段正好位于对话名称之后,但在编辑器窗口中,“名称”字段似乎略高于对话名称: 这是编辑器脚本:C# 如何在编辑器窗口中以相同的大小显示Inspector窗口?,c#,unity3d,C#,Unity3d,问题是,在Inspector中,它看起来很好,正如我所希望的,但在编辑器窗口中,控件和字段不在相同的位置 在屏幕截图中,检查器窗口位于右侧,编辑器窗口位于左侧。问题在于Inspector上的对话名称“名称”字段正好位于对话名称之后,但在编辑器窗口中,“名称”字段似乎略高于对话名称: 这是编辑器脚本: using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEditorIn
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
[CustomEditor(typeof(ConversationTrigger))]
public class ConversationTriggerEditor : Editor
{
private ConversationTrigger _conversationTrigger;
[SerializeField] private ReorderableList conversationsList;
private SerializedProperty _conversations;
private int _currentlySelectedConversationIndex = -1;
private int newSize = 0;
private Vector2 scrollPos;
private SerializedProperty conversationsCounter;
private readonly Dictionary<string, ReorderableList> _dialoguesListDict = new Dictionary<string, ReorderableList>();
private readonly Dictionary<string, ReorderableList> _sentencesListDict = new Dictionary<string, ReorderableList>();
private void OnEnable()
{
_conversationTrigger = (ConversationTrigger)target;
_conversations = serializedObject.FindProperty("conversations");
conversationsList = new ReorderableList(serializedObject, _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;
conversationsCounter = addedElement.FindPropertyRelative("ConversationIndex");
},
elementHeightCallback = (index) =>
{
return GetConversationHeight(_conversations.GetArrayElementAtIndex(index));
}
};
}
public override void OnInspectorGUI()
{
serializedObject.Update();
// if there are no elements reset _currentlySelectedConversationIndex
if (conversationsList.serializedProperty.arraySize - 1 < _currentlySelectedConversationIndex) _currentlySelectedConversationIndex = -1;
EditorGUILayout.LabelField("Conversations", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
{
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);
}
}
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Height(250));
GUILayout.Space(10);
conversationsList.DoLayoutList();
EditorGUILayout.EndScrollView();
if (GUILayout.Button("Save Conversations"))
{
_conversationTrigger.SaveConversations();
}
if (GUILayout.Button("Load Conversations"))
{
Undo.RecordObject(_conversationTrigger, "Loaded conversations from JSON");
_conversationTrigger.LoadConversations();
}
serializedObject.ApplyModifiedProperties();
}
#region Drawers
#region List Headers
private void DrawConversationsHeader(Rect rect)
{
//EditorGUI.LabelField(rect, "Conversations");
}
private void DrawDialoguesHeader(Rect rect)
{
EditorGUI.LabelField(rect, "Dialogues");
}
private void DrawSentencesHeader(Rect rect)
{
EditorGUI.LabelField(rect, "Sentences");
}
#endregion List Headers
#region Elements
private void DrawConversationsElement(Rect rect, int index, bool isActive, bool isFocused)
{
if (isActive) _currentlySelectedConversationIndex = index;
var conversation = _conversations.GetArrayElementAtIndex(index);
var position = new Rect(rect);
var name = conversation.FindPropertyRelative("Name");
var foldout = conversation.FindPropertyRelative("Foldout");
var dialogues = conversation.FindPropertyRelative("Dialogues");
string dialoguesListKey = conversation.propertyPath;
EditorGUI.indentLevel++;
{
// make the label be a foldout
//GUI.TextField(new Rect(position.x, position.y, 15, EditorGUIUtility.singleLineHeight), itemscounter.ToString());
foldout.boolValue = EditorGUI.Foldout(new Rect(position.x, position.y, 10, EditorGUIUtility.singleLineHeight), foldout.boolValue, "Conversation Name ", true);
name.stringValue = EditorGUI.TextField(new Rect(position.x + 120, position.y, 244, EditorGUIUtility.singleLineHeight), name.stringValue);
if (foldout.boolValue)
{
// draw the name field
//name.stringValue = EditorGUI.TextField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), name.stringValue);
position.y += EditorGUIUtility.singleLineHeight;
if (!_dialoguesListDict.ContainsKey(dialoguesListKey))
{
// create reorderabl list and store it in dict
var dialoguesList = new ReorderableList(conversation.serializedObject, dialogues)
{
displayAdd = true,
displayRemove = true,
draggable = true,
drawHeaderCallback = DrawDialoguesHeader,
drawElementCallback = (convRect, convIndex, convActive, convFocused) => { DrawDialoguesElement(_dialoguesListDict[dialoguesListKey], convRect, convIndex, convActive, convFocused); },
elementHeightCallback = (dialogIndex) =>
{
return GetDialogueHeight(_dialoguesListDict[dialoguesListKey].serializedProperty.GetArrayElementAtIndex(dialogIndex));
},
onAddCallback = (list) =>
{
list.serializedProperty.arraySize++;
var addedElement = list.serializedProperty.GetArrayElementAtIndex(list.serializedProperty.arraySize - 1);
var newDialoguesName = addedElement.FindPropertyRelative("Name");
var newDialoguesFoldout = addedElement.FindPropertyRelative("Foldout");
var sentences = addedElement.FindPropertyRelative("Sentences");
newDialoguesName.stringValue = "";
newDialoguesFoldout.boolValue = true;
sentences.arraySize = 0;
}
};
_dialoguesListDict[dialoguesListKey] = dialoguesList;
}
_dialoguesListDict[dialoguesListKey].DoList(new Rect(position.x, position.y, position.width, position.height - EditorGUIUtility.singleLineHeight));
}
}
EditorGUI.indentLevel--;
}
private void DrawDialoguesElement(ReorderableList list, Rect rect, int index, bool isActive, bool isFocused)
{
if (list == null) return;
var dialog = list.serializedProperty.GetArrayElementAtIndex(index);
var position = new Rect(rect);
var foldout = dialog.FindPropertyRelative("Foldout");
var name = dialog.FindPropertyRelative("Name");
{
// make the label be a foldout
foldout.boolValue = EditorGUI.Foldout(new Rect(position.x, position.y, 10, EditorGUIUtility.singleLineHeight), foldout.boolValue, foldout.boolValue ? "" : name.stringValue);
var sentencesListKey = dialog.propertyPath;
var sentences = dialog.FindPropertyRelative("Sentences");
if (foldout.boolValue)
{
// draw the name field
name.stringValue = EditorGUI.TextField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), name.stringValue);
position.y += EditorGUIUtility.singleLineHeight;
if (!_sentencesListDict.ContainsKey(sentencesListKey))
{
// create reorderabl list and store it in dict
var sentencesList = new ReorderableList(sentences.serializedObject, sentences)
{
displayAdd = true,
displayRemove = true,
draggable = true,
// header for the dialog list
drawHeaderCallback = DrawSentencesHeader,
// how a sentence is displayed
drawElementCallback = (sentenceRect, sentenceIndex, sentenceIsActive, sentenceIsFocused) =>
{
var sentence = sentences.GetArrayElementAtIndex(sentenceIndex);
// draw simple textArea for sentence
sentence.stringValue = EditorGUI.TextArea(sentenceRect, sentence.stringValue);
},
// Sentences have simply a fixed height of 2 lines
elementHeight = EditorGUIUtility.singleLineHeight * 2,
// when a sentence is added
onAddCallback = (sentList) =>
{
sentList.serializedProperty.arraySize++;
var addedElement = sentList.serializedProperty.GetArrayElementAtIndex(sentList.serializedProperty.arraySize - 1);
addedElement.stringValue = "";
}
};
// store the created ReorderableList
_sentencesListDict[sentencesListKey] = sentencesList;
}
// Draw the list
_sentencesListDict[sentencesListKey].DoList(new Rect(position.x, position.y, position.width, position.height - EditorGUIUtility.singleLineHeight));
}
}
}
#endregion Elements
#endregion Drawers
#region Helpers
#region HeightGetter
/// <summary>
/// Returns the height of given Conversation property
/// </summary>
/// <param name="conversation"></param>
/// <returns>height of given Conversation property</returns>
private float GetConversationHeight(SerializedProperty conversation)
{
var foldout = conversation.FindPropertyRelative("Foldout");
// if not foldout the height is simply 1 line
var height = EditorGUIUtility.singleLineHeight;
// otherwise we sum up every controls and child heights
if (foldout.boolValue)
{
// we need some more lines:
// for the Name field,
// the list header,
// the list buttons and a bit buffer
height += EditorGUIUtility.singleLineHeight * 5;
var dialogues = conversation.FindPropertyRelative("Dialogues");
for (var d = 0; d < dialogues.arraySize; d++)
{
var dialog = dialogues.GetArrayElementAtIndex(d);
height += GetDialogueHeight(dialog);
}
}
return height;
}
/// <summary>
/// Returns the height of given Dialogue property
/// </summary>
/// <param name="dialog"></param>
/// <returns>height of given Dialogue property</returns>
private float GetDialogueHeight(SerializedProperty dialog)
{
var foldout = dialog.FindPropertyRelative("Foldout");
// same game for the dialog if not foldout it is only a single line
var height = EditorGUIUtility.singleLineHeight;
// otherwise sum up controls and child heights
if (foldout.boolValue)
{
// we need some more lines:
// for the Name field,
// the list header,
// the list buttons and a bit buffer
height += EditorGUIUtility.singleLineHeight * 4;
var sentences = dialog.FindPropertyRelative("Sentences");
// the sentences are easier since they always have the same height
// in this example 2 lines so simply do
// at least have space for 1 sentences even if there is none
height += EditorGUIUtility.singleLineHeight * Mathf.Max(1, sentences.arraySize) * 2;
}
return height;
}
#endregion
#endregion Helpers
}
这是编辑器窗口脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
public class ConversationsEditorWindow : EditorWindow
{
private ConversationTriggerEditor editor;
[MenuItem("Conversations/Conversations System")]
static void Init()
{
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>();
var ff = FindObjectOfType<ConversationTrigger>();
window.position = new Rect(x, y, width, height);
window.editor = (ConversationTriggerEditor)Editor.CreateEditor(ff);
}
void OnGUI()
{
editor.OnInspectorGUI();
}
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEditor;
使用UnityEditorInternal;
使用UnityEngine;
公共类会话编辑器窗口:编辑器窗口
{
私人对话触发器编辑器;
[MenuItem(“对话/对话系统”)]
静态void Init()
{
常数int宽度=800;
const int height=800;
var x=(Screen.currentResolution.width-width)/2;
变量y=(Screen.currentResolution.height-height)/2;
var window=GetWindow();
var ff=FindObjectOfType();
window.position=新矩形(x,y,宽度,高度);
window.editor=(ConversationTriggerEditor)editor.CreateEditor(ff);
}
void OnGUI()
{
OnInspectorGUI();
}
}
区别似乎在于,Inspector位置中的指的是显示相应字段/属性的Rect
。在EditorWindow中,可以看到它从左上角开始,而在Inspector中,有一点偏移。然后,对于编辑器窗口中的对话名称
标签,标签/折页和ReorderableList的grib图标之间也有一点偏移。。不知道如何解决这个问题,您可以尝试在EditorGUI.indentLevel++中包装editor.OnInspectorGUI()
代码>和EditorGUI.indentLevel--代码>不同之处似乎在于检查器中的位置
指的是显示相应字段/属性的矩形。在EditorWindow中,可以看到它从左上角开始,而在Inspector中,有一点偏移。然后,对于编辑器窗口中的对话名称
标签,标签/折页和ReorderableList的grib图标之间也有一点偏移。。不知道如何解决这个问题,您可以尝试在EditorGUI.indentLevel++中包装editor.OnInspectorGUI()
代码>和EditorGUI.indentLevel--代码>
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
public class ConversationsEditorWindow : EditorWindow
{
private ConversationTriggerEditor editor;
[MenuItem("Conversations/Conversations System")]
static void Init()
{
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>();
var ff = FindObjectOfType<ConversationTrigger>();
window.position = new Rect(x, y, width, height);
window.editor = (ConversationTriggerEditor)Editor.CreateEditor(ff);
}
void OnGUI()
{
editor.OnInspectorGUI();
}
}