首页 > 解决方案 > 如何从编辑器脚本中的 int 字段控件中移除焦点?

问题描述

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");

                GUI.FocusControl("Load Conversations");
            },

            elementHeightCallback = (index) =>
            {
                return GetConversationHeight(_conversations.GetArrayElementAtIndex(index));
            }
        };
    }

我稍后在脚本中有一个 OnInspectorGUI 内的按钮:

if (GUILayout.Button("Load Conversations"))
        {
            Undo.RecordObject(_conversationTrigger, "Loaded conversations from JSON");
            _conversationTrigger.LoadConversations();
        }

但它不起作用我需要单击编辑器中的任何其他控件才能使 int 字段中的更改值生效。

在这里,我使用 IntField :

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

当我在 IntField 中输入新的大小值时,它会实时更改列表并添加/删除项目。

但是,如果我将 IntField 设置为 0,然后单击“加载对话”按钮,它将加载项目,但 intfield 中的值仍将为 0,而不是更改为加载项目的数量。

只有当我单击编辑器中的另一个控件或什至单击 PC 中的其他窗口时,它才会将 intfield 值更改为加载的项目数值。

标签: c#unity3d

解决方案


您可以使用EditorGUI.FocusTextInControl.


通常你会打电话给

GUI.SetNextControlName("MyTextField");

为了给下一个显示的字段设置一个特定的名称(把它想象成一个标签),然后在一些事件调用上

 EditorGUI.FocusTextInControl("MyTextField");

以便将焦点设置到该字段。


在您的情况下,只想放松焦点而不是专注于您可以简单使用的任何领域

EditorGUI.FocusTextInControl(null);

推荐阅读