如何在 Inspector 中设置 GUI.Button 的位置?
How can I set position of a GUI.Button in Inspector?
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
字段之前,并且始终在最后一个对话项目之后,在本例中为锁定的房间。如果我要添加一个新项目,按钮应该保留在新添加的项目之后和 Canvas
字段之前。
我猜 Rect
的这个值是错误的,使按钮位于 window 之外。
这是 Inspector 的屏幕截图:
Rect
的值是 positionX
、positionY
、width
和 height
,对于 Inspector,它们以像素为单位。所以
new Rect(0.1f,0.5f,0.1f,0.1f)
只是在当前 Inspector 的 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
。
不过,我一般建议不要混合使用 GUI
和 GUILayout
东西。这有点像在 css
中混合 static
和 relative
..
根据您想在此处更改的具体内容,您可能更愿意使用可选的 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(...))
为了在按钮和之前的控件之间有一个小的默认值 space 或 GUILayout.Space
例如
GUILayout.Space(30);
if(GUILayout.Button(...))
以像素为单位设置固定 space。
针对您的实际问题
如果你真的想在控件之间放置一个按钮,那么你就不会为整个检查器实现编辑器而不是使用 DrawDefaultInspector
,因为这也意味着你必须 space 按钮。否则,您可能会在彼此之上获得多个控件。
我不会在这里为你做那个。我们甚至看不到您 类 的 fields/types。
但是因为你在那里使用 list/array 我(就像我经常做的那样)再次强烈建议使用未记录的 ReorderableList
它不仅非常花哨而且允许你重新排列项目通过拖放在列表中,但也默认实现 Add
和 Remove
按钮。
请问你为什么这样做
conversationtrigger = FindObjectOfType<ConversationTrigger>();
一旦您处理不活动的游戏对象、禁用的 ConversationTrigger
、预制件或场景中这些组件的多个,这就会失败。
在编辑器中,您已经在 target
中获得了当前检查的组件。你所要做的就是像
一样投射它
conversationtrigger = (ConversationTrigger) target;
注意:在智能手机上打字,因此不提供保修,但我希望这个想法能得到理解
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
字段之前,并且始终在最后一个对话项目之后,在本例中为锁定的房间。如果我要添加一个新项目,按钮应该保留在新添加的项目之后和 Canvas
字段之前。
我猜 Rect
的这个值是错误的,使按钮位于 window 之外。
这是 Inspector 的屏幕截图:
Rect
的值是 positionX
、positionY
、width
和 height
,对于 Inspector,它们以像素为单位。所以
new Rect(0.1f,0.5f,0.1f,0.1f)
只是在当前 Inspector 的 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
。
不过,我一般建议不要混合使用 GUI
和 GUILayout
东西。这有点像在 css
中混合 static
和 relative
..
根据您想在此处更改的具体内容,您可能更愿意使用可选的 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(...))
为了在按钮和之前的控件之间有一个小的默认值 space 或 GUILayout.Space
例如
GUILayout.Space(30);
if(GUILayout.Button(...))
以像素为单位设置固定 space。
针对您的实际问题
如果你真的想在控件之间放置一个按钮,那么你就不会为整个检查器实现编辑器而不是使用 DrawDefaultInspector
,因为这也意味着你必须 space 按钮。否则,您可能会在彼此之上获得多个控件。
我不会在这里为你做那个。我们甚至看不到您 类 的 fields/types。
但是因为你在那里使用 list/array 我(就像我经常做的那样)再次强烈建议使用未记录的 ReorderableList
它不仅非常花哨而且允许你重新排列项目通过拖放在列表中,但也默认实现 Add
和 Remove
按钮。
请问你为什么这样做
conversationtrigger = FindObjectOfType<ConversationTrigger>();
一旦您处理不活动的游戏对象、禁用的 ConversationTrigger
、预制件或场景中这些组件的多个,这就会失败。
在编辑器中,您已经在 target
中获得了当前检查的组件。你所要做的就是像
conversationtrigger = (ConversationTrigger) target;
注意:在智能手机上打字,因此不提供保修,但我希望这个想法能得到理解