为什么BeginScrollView在检查器编辑器脚本中可以正常工作,但在编辑器窗口脚本中却不能正常工作?

时间:2019-07-08 15:10:27

标签: c# unity3d

这是检查器编辑器脚本,可以很好地与滚动视图一起使用:

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字段中更改编辑器窗口中的对话数或我需要首先用鼠标单击更改字段上方的窗口的空白区域时的对话数时使更改生效。然后它折叠了根,我需要再次扩展它:

在屏幕截图中,有一个对话:

One Conversation

当我键入并改为将1更改为20时,什么也没发生: 仍然只有一次对话:

Still one conversation

我需要先关闭“对话”根目录:

Closed the conversations

现在,当我单击它并再次打开它时,我将看到20个对话:

20 Conversations

  1. 在更改对话和/或对话和/或句子的大小时,如何实时添加/删除项目?

  2. 在上一个屏幕截图中,您可以看到滚动视图栏没有移动。我无法上下移动它。

1 个答案:

答案 0 :(得分:1)

所以问题似乎实际上是:为什么Editorwindow中的List没有得到更新?

我想我曾告诉过您一次,您应该在自定义编辑器脚本中使用SerializedProperty之前,不要直接更改组件值而不将对象标记为 dirty

[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();
    }
}

enter image description here


并使用它来修复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();
    }
}
相关问题