如何在Inspector中设置GUI.Button的位置?

时间:2019-05-17 02:20:12

标签: c# unity3d unity3d-editor

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

1 个答案:

答案 0 :(得分:2)

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

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

仅在当前Inspector的0.1 x 0.1像素位置上产生一个很小的0.1 ,0.5像素大小按钮。由于您无法在屏幕上显示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")
    ...

将按钮I的下一行置于最后一个控件的下方,并将其大小设置为100px * 30px


但是,我通常建议不要混用GUIGUILayout的东西。有点像在static中混合relativecss ..


根据您要在此处更改的确切内容,您可能希望使用可选的options参数,例如使用

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

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

来进行更改
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,这不仅非常好用,而且允许您通过以下方式重新排列列表中的项目:拖放,但默认情况下还实现了AddRemove按钮。


我也可以问你为什么

conversationtrigger = FindObjectOfType<ConversationTrigger>();

一旦您要处理无效的GameObject,禁用的ConversationTrigger,Prefab或场景中的多个组件,此操作就会失败。

在编辑器中,您已经在target中获得了当前检查的组件。您要做的就是将其投射为

conversationtrigger = (ConversationTrigger) target;

注意:在智能手机上键入内容,因此没有保修,但我希望这个主意会清楚