【问题标题】:How can I set position of a GUI.Button in Inspector?如何在 Inspector 中设置 GUI.Button 的位置?
【发布时间】:2019-05-17 02:20:12
【问题描述】:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

[CustomEditor(typeof(ConversationTrigger))]
public class ConversationTriggerEditor : Editor
{
    private ConversationTrigger conversationtrigger;

    private void OnEnable()
    {
        conversationtrigger = FindObjectOfType<ConversationTrigger>();
    }

    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        if(GUI.Button(new Rect(0.1f,0.5f,0.1f,0.1f), "Add new item"))
        {
            conversationtrigger.conversations.Add(new Conversation());
        }

        if (GUILayout.Button("Save Conversations"))
        {
            conversationtrigger.SaveConversations();
        }

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

我试过这条线:

if(GUI.Button(new Rect(0.1f,0.5f,0.1f,0.1f), "Add new item"))

但这会使按钮像删除一样消失。 如果我使用GUILayout.Button,我会看到按钮,但我无法设置按钮位置,所以我使用GUI.Button

我想将按钮 "Add new item" 放在 Canvas 字段之前,并且总是在最后一个对话项目之后,在本例中是 Locked Room。如果我要添加一个新项目,按钮应该保留在新添加的项目之后和Canvas 字段之前。

我猜Rect 的这个值是错误的,使按钮位于窗口外。

这是 Inspector 的截图:

【问题讨论】:

    标签: c# unity3d unity3d-editor


    【解决方案1】:

    Rect 的值是 positionXpositionYwidthheight,对于 Inspector,它们以像素为单位。所以

    new Rect(0.1f,0.5f,0.1f,0.1f)
    

    只会在当前检查器的0.1 ,0.5 像素位置上生成一个非常小的0.1 x 0.1 像素大小按钮。由于您无法在屏幕上显示大小为0.1 像素的内容,因此它是不可见的。


    Afaik 您可以使用GUILayoutUtility.GetLastRect 来获取按钮之前最后一个控件的Rect,然后使用该矩形放置按钮,例如

    Rect lastRect = GUILayoutUtility.GetLastRect();
    
    Rect buttonRect = new Rect(lastRect.x, lastRect.y + EditorGUIUtility.singleLineHeight, 100, 30);
    
    if(GUI.Button(buttonRect, "AddNewItem")
        ...
    

    将按钮放在最后一个控件下的下一行并将其大小设置为100px * 30px


    不过,我一般建议不要混合使用 GUIGUILayout 的东西。这有点像在css 中混合staticrelative ..


    根据您要在此处更改的具体内容,您可能更愿意使用可选的options 参数,例如使用

    更改按钮的高度和宽度
    GUILayout.Button("AddNewItem", GUILayout.With(100), GUILayout.Height(30));
    

    您也可以通过临时更改 EditorGUI.indentLevel 来更改按钮在 X 轴上的起始位置,例如

    EditorGUI.indentLevel++
    GUILayout.Button("AddNewItem", GUILayout.With(100), GUILayout.Height(30));
    EditorGUI.indentLevel--;
    

    要更改 Y 方向的位置,您可以使用 EditorGUILayout.Space

    EditorGUILayout.Space();
    if(GUILayout.Button(...))
    

    为了在按钮和控件之前或GUILayout.Space 之间留一个小的默认空间,例如

    GUILayout.Space(30);
    if(GUILayout.Button(...))
    

    以像素为单位设置固定空间。


    您的实际问题

    如果您真的想在控件之间放置一个按钮,然后您不会为整个检查器实现编辑器而不是使用DrawDefaultInspector,因为这也意味着您必须为按钮腾出空间。否则,您可能会得到多个控件。

    我不会在这里为你这样做。我们甚至看不到您的类的字段/类型。

    但是由于您在那里使用列表/数组,所以我(就像我经常做的那样)再次强烈建议使用未记录的ReorderableList,它不仅非常精美,而且允许您通过拖动和重新排列列表中的项目drop 但也默认实现AddRemove 按钮。


    请问你为什么这样做

    conversationtrigger = FindObjectOfType<ConversationTrigger>();
    

    当您处理不活动的游戏对象、禁用的ConversationTrigger、预制件或场景中的多个组件时,这将失败。

    在编辑器中,您已经在target 中获得了当前检查的组件。您所要做的就是像这样投射它

    conversationtrigger = (ConversationTrigger) target;
    

    注意:在智能手机上打字,所以没有保修,但我希望这个想法能清楚

    【讨论】:

    • 我能够在您提供的链接中使用 ReorderableList。现在我可以拖动项目并使用 + 和 - 来添加/删除项目。但是,当单击 + 时,我该如何做到这一点,它将添加我的列表类型(对话)的新空项?当我双击其中一个项目或制作一个箭头来折叠项目并在我的问题中显示我的屏幕截图中的所有孩子时,我该如何做到这一点?
    • 我很乐意在新问题中帮助您解决这些问题;)
    猜你喜欢
    • 2015-07-17
    • 1970-01-01
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 2017-01-02
    • 2015-11-12
    • 2018-11-13
    相关资源
    最近更新 更多