Reputation: 11317
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();
}
}
}
I tried this line :
if(GUI.Button(new Rect(0.1f,0.5f,0.1f,0.1f), "Add new item"))
But that make the button vanished like deleted.
If I'm using GUILayout.Button
I will see the button but then I can't set the button position so I'm using GUI.Button
.
I want to position the button "Add new item"
before the Canvas
field and always after the last conversation item, in this case the Locked Room. And if I will add a new item the button should stay after the new added item and before the Canvas
field.
I guess this values of the Rect
are wrong making the button to be positioned out of the window.
This is a screenshot of the Inspector :
Upvotes: 3
Views: 8647
Reputation: 90659
The values for the Rect
are positionX
, positionY
, width
and height
and for the Inspector they are in pixels. So
new Rect(0.1f,0.5f,0.1f,0.1f)
simply results in a really tiny little 0.1 x 0.1
pixel size button on the position 0.1 ,0.5
pixels of the current Inspector. Since you can't display something with size 0.1
pixels on the screen it is invisible.
Afaik you can use GUILayoutUtility.GetLastRect
in order to get the Rect
of the last control before the button and then place your button using that rect like e.g.
Rect lastRect = GUILayoutUtility.GetLastRect();
Rect buttonRect = new Rect(lastRect.x, lastRect.y + EditorGUIUtility.singleLineHeight, 100, 30);
if(GUI.Button(buttonRect, "AddNewItem")
...
to place the button I the next line under the last control and set it's size to 100px * 30px
.
I would however in general recommend to not mix GUI
and GUILayout
stuff. It is kind of the same like mixing static
and relative
in css
..
Depending on what exactly it is you want to change here you might rather want to use the optional options
parameter to e.g. change the buttons height and width using
GUILayout.Button("AddNewItem", GUILayout.With(100), GUILayout.Height(30));
where the button starts in the X axis you could also change by temporarily change the EditorGUI.indentLevel e.g.
EditorGUI.indentLevel++
GUILayout.Button("AddNewItem", GUILayout.With(100), GUILayout.Height(30));
EditorGUI.indentLevel--;
For changing the position in Y direction you could either use EditorGUILayout.Space
EditorGUILayout.Space();
if(GUILayout.Button(...))
in order to have a small default space between the button and the control before or GUILayout.Space
like e.g.
GUILayout.Space(30);
if(GUILayout.Button(...))
to set a fixed space in pixels.
To your actual question
If you really want to place a button in between the controls before you won't come around implementing the Editor for the entire inspector instead of using DrawDefaultInspector
since it also means that you would have to make space for the button. Otherwise you might get multiple controls on top of each other.
I won't do that for you here. We can't even see the fields/types of your classes.
But since you are using a list/array there I (like I do quite often) once more strongly recommend to use the undocumented ReorderableList
which not only is extremely fancy and allows you to rearrange items within the list by drag and drop but also implements Add
and Remove
buttons by default.
May I also ask why you do
conversationtrigger = FindObjectOfType<ConversationTrigger>();
This will fail as soon as you are dealing with an inactive GameObject, a disabled ConversationTrigger
, a Prefab or simply multiple of those components in the scene.
In the Editor you already get the currently inspected component in target
. All you have to do is to cast it like
conversationtrigger = (ConversationTrigger) target;
Note: Typed on smartphone so no warranty but I hope the idea gets clear
Upvotes: 3