c# - 为什么 BeginScrollView 在检查器编辑器脚本中工作正常,但在编辑器窗口脚本中不起作用?
问题描述
这是与滚动视图一起正常工作的检查器编辑器脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
[CustomEditor(typeof(ConversationTrigger))]
public class ConversationTriggerEditor : Editor
{
private Vector2 scrollPos;
private ConversationTrigger conversationtrigger;
private void OnEnable()
{
conversationtrigger = (ConversationTrigger)target;
}
public override void OnInspectorGUI()
{
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Height(250));
DrawDefaultInspector();
EditorGUILayout.EndScrollView();
if (GUILayout.Button("Add new conversation"))
{
conversationtrigger.conversations.Add(new Conversation());
}
GUILayout.Space(10);
if (conversationtrigger.conversations.Count == 0)
{
GUI.enabled = false;
}
else
{
GUI.enabled = true;
}
if (GUILayout.Button("Remove conversation"))
{
if (conversationtrigger.conversations.Count > 0)
conversationtrigger.conversations.RemoveAt(conversationtrigger.conversations.Count - 1);
}
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();
}
}
}
这是使用和显示与检查器相同的编辑器窗口脚本,但在编辑器窗口中滚动视图不起作用。我可以向上/向下滚动滚动条,根本不动:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
public class ConversationsEditorWindow : EditorWindow
{
Vector2 scrollPos;
[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;
GetWindow<ConversationsEditorWindow>().position = new Rect(x, y, width, height);
}
void OnGUI()
{
var ff = FindObjectOfType<ConversationTrigger>();
EditorGUILayout.BeginVertical();
EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Width(800), GUILayout.Height(800));
var editor = Editor.CreateEditor(ff);
var tar = editor.targets;
editor.OnInspectorGUI();
EditorGUILayout.EndScrollView();
EditorGUILayout.EndVertical();
Repaint();
}
}
另一个令人烦恼的事情是,当我在 int 字段中更改编辑器窗口中的对话数量或我需要首先用鼠标单击更改字段上方窗口的某个空白区域以使对话的数量时更改生效。然后它正在折叠根,我需要再次展开它:
在屏幕截图中有一个对话:
当我输入并将 1 例如更改为 20 时,没有任何反应:仍然只有一个对话:
我需要先关闭对话根:
现在,当我单击它并再次打开它时,我将看到 20 个对话:
在更改对话和/或对话和/或句子的大小时,我该如何做到这一点,它将实时添加/删除项目?
在最后一个屏幕截图中,您可以看到没有移动的滚动视图栏。我不能向上/向下移动它。
解决方案
所以问题似乎实际上是:为什么编辑器窗口中的列表没有更新?
我想我在你应该SerializedProperty
在自定义编辑器脚本中使用之前告诉过你一次,不要直接更改组件值而不将对象标记为脏。
[CustomEditor(typeof(ConversationTrigger))]
public class ConversationTriggerEditor : Editor
{
private Vector2 scrollPos;
private SerializedProperty conversations;
private ConversationTrigger conversationTrigger;
private void OnEnable()
{
conversations = serializedObject.FindProperty("conversations");
conversationTrigger = (ConversationTrigger)target;
}
public override void OnInspectorGUI()
{
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Height(250));
DrawDefaultInspector();
EditorGUILayout.EndScrollView();
// Load the current values from the real component into the serialized copy
serializedObject.Update();
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"))
{
// Depending on what this does you should consider to also
// change it to using the SerializedProperties!
Undo.RecordObject(conversationtrigger, "Loaded conversations from JSON");
conversationTrigger.LoadConversations();
}
serializedObject.ApplyModifiedProperties();
}
}
如您所见,滚动非常适合我:
而且我只能再一次强烈推荐ReorderableList
用于你正在做的事情。设置起来稍微复杂一些,但功能非常强大:
[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,
drawHeaderCallback = rect =>
{
EditorGUI.LabelField(new Rect(rect.x, rect.y, 100, rect.height), "Conversations", EditorStyles.boldLabel);
var newSize = EditorGUI.IntField(new Rect(rect.x + 100, rect.y, rect.width - 100, rect.height), conversations.arraySize);
conversations.arraySize = Mathf.Max(0, newSize);
},
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();
scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Height(250));
GUILayout.Space(10);
conversationList.DoLayoutList();
EditorGUILayout.EndScrollView();
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();
}
}
并使用它来修复 EditorWindow
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();
}
}
推荐阅读
- javascript - 在 React Native 中让“视图”填满整个屏幕
- php - Wordpress setup_postdata 不返回任何内容
- javascript -
- python - Pulumi python资源命名约定
- flutter - 我怎样才能制作相同样式的下拉菜单
- python - 如何解决:TypeError:JSON 对象必须是 str、bytes 或 bytearray,而不是 TextIOWrapper
- google-cloud-storage - 无法通过 gsutil 从 Google Cloud SDK 下载更新的文件(从 6 月 4 日起)
- laravel - 如何使用 Vuejs 在数组中分配键索引
- django - 如何将 SQLlite 连接到 Django 中的项目(不是应用程序)
- postman - 在 Postman 测试中获取时间阶段