- Home /
DropDownList with string array in Editor Inspector
I understand that you can do the dropdownlist with enums already automatically, but I have a dynamic list of strings from file/game/input/etc stored into a List that I want to be selectable in the editor. How would I go about doing that? Any specifics into the correct direction would be greatly appreciated!
Answer by hiddenspring81 · May 18, 2013 at 04:25 PM
You should look at EditorGUILayout.Popup. This sounds like exactly what you're looking for. You'd use it as follows,
[CustomEditor(typeof(SomeClass))]
public class SomeEditor : Editor
{
string[] _choices = new [] { "foo", "foobar" };
int _choiceIndex = 0;
public override void OnInspectorGUI ()
{
// Draw the default inspector
DrawDefaultInspector();
_choiceIndex = EditorGUILayout.Popup(_choiceIndex, _choices);
var someClass = target as SomeClass;
// Update the selected choice in the underlying object
someClass.choice = _choices[_choiceIndex];
// Save the changes back to the object
EditorUtility.SetDirty(target);
}
}
How would I go about using the _choiceIndex int or the string itself in the SomeClass.cs script?
It's actually pretty simple. If SomeClass
looked like the following,
public class SomeClass : $$anonymous$$onoBehaviour
{
public string choice;
}
You could set the choice
variable of SomeClass
using the following,
void OnGUI ()
{
// Choose an option from the list
_choiceIndex = EditorGUILayout.Popup(_choiceIndex, _choices);
// Update the selected option on the underlying instance of SomeClass
var someClass = target as SomeClass;
someClass.choice = _choices[_choiceIndex];
}
Thanks! However there's still an issue. If I set the value it stays on the editor, but when I play the scene in the editor, the value resets. Is there anyway for the value to be permanent?
There are two reasons why that might happen. First, make sure that the variable in your class is either public
or that it has the Serializable attribute applied to it. For example
public class SomeClass : $$anonymous$$onoBehaviour
{
// This will work
public string choice;
// This also works
[Serializable]
private string _otherChoice;
public string OtherChoice { get { return _otherChoice: } set { _otherChoice = value; } }
// This doesn't work
public string AnotherChoice { get; set; }
// And this also doesn't work
private string _yetAnotherChoice;
public string YetAnotherChoice { get { return _yetAnotherChoice; } set { _yetAnotherChoice = value; } }
}
Finally, you should also try calling EditorUtility.SetDirty() inside of your OnGUI()
method at the end of your custom editor, which will ensure that any modifications to the asset will be saved.
void OnGUI ()
{
// Custom inspector code goes here
EditorUtility.SetDirty(target);
}
Thanks a lot! That really helped! I had it as private, hence it didn't work.
I'm going to accept this answer, but just to note here ins$$anonymous$$d of "void OnGUI()" I had to use "public override void OnInspectorGUI()" for it to work. Also, if you want to also show the default inspector property editor stuff, you have to call either "DrawDefaultInspector()" or "base.OnInspectorGUI()". Oh and you have to put the script inside a folder named Editor for it to work!
Answer by lwilliams_dev · Jan 27, 2016 at 05:48 AM
I got around the problem of the _choice index resetting by setting the _choice index to the value in my array.
public override void OnInspectorGUI()
{
// Draw the default inspector
DrawDefaultInspector();
// Set the choice index to the previously selected index
_choiceIndex = Array.IndexOf(_choices, sameClass.choice);
// If the choice is not in the array then the _choiceIndex will be -1 so set back to 0
if (_choiceIndex < 0)
_choiceIndex = 0;
_choiceIndex = EditorGUILayout.Popup(_choiceIndex, _choices);
var someClass = target as SomeClass;
// Update the selected choice in the underlying object
someClass.choice = _choices[_choiceIndex];
// Save the changes back to the object
EditorUtility.SetDirty(target);
}
Incredibly helpful. I wonder why it resets in the first place however?
Answer by ShawnFeatherly · Apr 19, 2018 at 01:00 AM
Found this gist that creates an attribute allowing you to create a dropdown out of any string field using.
[StringInList("Cat","Dog")]
public string Animal;
.
For dynamic lists he uses reflection to call a function that returns a string[].
[StringInList(typeof(PropertyDrawersHelper), "AllSceneNames")]
public string SceneName;
Answer by kamicazer7 · Dec 28, 2016 at 02:40 PM
I just came across this post, to learn how to to customize the editor. However some of the information here no longer works with the current Unity version(5.5). For this, I followed the Scripting API: Editor page and also used some of the code available here. Here is how I achieved the results with the new version:
using UnityEditor;
using UnityEngine;
using System.Collections;
using System;
// Custom Editor using SerializedProperties.
// Automatic handling of multi-object editing, undo, and prefab overrides.
[CustomEditor(typeof(MyPlayer))]
[CanEditMultipleObjects]
public class MyPlayerEditor : Editor
{
SerializedProperty orientationProp;
string[] _choices = new[] { "Up", "Down" , "Left" , "Right" };
int _choiceIndex = 0;
void OnEnable()
{
// Setup the SerializedProperties.
orientationProp = serializedObject.FindProperty("gameOrientation");
// Set the choice index to the previously selected index
_choiceIndex = Array.IndexOf(_choices, orientationProp.stringValue);
}
public override void OnInspectorGUI()
{
// Update the serializedProperty - always do this in the beginning of OnInspectorGUI.
serializedObject.Update();
//doing the orientation thing
_choiceIndex = EditorGUILayout.Popup("Orientation", _choiceIndex, _choices);
if (_choiceIndex < 0)
_choiceIndex = 0;
orientationProp.stringValue = _choices[_choiceIndex];
// Apply changes to the serializedProperty - always do this in the end of OnInspectorGUI.
serializedObject.ApplyModifiedProperties();
}
and the class MyPlayer example class simply has the public declaration.
public class MyPlayer : MonoBehaviour
{
public string gameOrientation;
}
Answer by astracat111 · Apr 12, 2017 at 09:17 PM
If you're doing an inspector and you want that inspector to have it's own custom gui style without messing with the others, you could do something like this:
//save as Editor_Inspectors_MyScript.cs in the Editor folder...Works if you //attach a 'MyInspectorScript.cs' to an object. Then look at it in the //inspector to see the changes.
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(MyInspectorScript))]
public class Editor_Inspectors_MyScript : Editor {
GUIStyle guiStyle;
MyInspectorScript myInspectorScript;
void OnEnable() {
myInspectorScript = (MyInspectorScript)target;
guiStyle = new GUIStyle ();
}
public override void OnInspectorGUI() {
guiStyle.fontSize = 50;
guiStyle.font = "Arial"; //or whatever
EditorGUILayout.Label ("Hello world", choices,guiStyle);
}
}
Your answer
Follow this Question
Related Questions
Can Editor Windows function like the inspector ? 2 Answers
How To Draw a PropertyDrawer within a PropertyDrawer 0 Answers
Public Sterialized Varibal Not Apearing In Inspector 1 Answer
Can a GameObject inside of an array be made "accessible" from the editor? 2 Answers
How to change inspector with non-Monobehaviour objects ? 1 Answer