首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么BeginScrollView在检查器编辑器脚本中可以正常工作,但在编辑器窗口脚本中不能工作?

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

Stack Overflow用户
提问于 2019-07-08 23:10:27
回答 1查看 1.1K关注 0票数 0

以下是能够很好地与滚动视图配合使用的检查器编辑器脚本:

代码语言:javascript
复制
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();
        }
    }
}

这是编辑器窗口脚本,其使用和显示与在检查器中相同,但在编辑器窗口中滚动视图不起作用。我可以向上/向下滚动滚动条,但完全不动:

代码语言:javascript
复制
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个对话:

  1. 如何在更改对话和/或对话和/或句子的大小时实时添加/删除项目?
  2. 在最后一个屏幕截图中,您可以看到滚动条没有移动。我不能向上/向下移动。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-09 02:39:12

所以问题看起来实际上是:为什么编辑器窗口中的列表没有更新?

我想我以前告诉过你一次,你应该在自定义编辑器脚本中使用SerializedProperty,不要在没有将对象标记为脏的情况下直接改变组件值。

代码语言:javascript
复制
[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来完成您的工作。它的设置稍微复杂一些,但却非常强大:

代码语言:javascript
复制
[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

代码语言:javascript
复制
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();
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56937861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档