- Home /
Creating enum using a string array
I'm trying to recreate the Tag dropdown menu.
It's possible to create a string array that contains all the Tags in the project using
public string[] tagsStr = UnityEditorInternal.InternalEditorUtility.tags;
So say I have a public tags enum ,
enum Tags {}
How do I populate it with my tagsStr array? And will this need to be a custom inspector as I assume the Enum needs to be populated preenum runtime?
Those only works if you have an enum with all those values already. $$anonymous$$ost on the first SO question didn't understand the question properly because the OP had an hardcoded enum in his question. However he said that he's getting the names from an API callback as string array, so he doesn't know what members the enum needs to have. Like i said in my answer, there's actually no point in creating an enum "on the fly" at runtime.
Answer by Bunny83 · Dec 14, 2014 at 03:17 PM
No, that's not possible. An Enum need to be compiled at compile time and not at runtime. Even when it's possible to create an enum type with the members defined by the elements of a string array, you can't use the enum in your code since it doesn't exist at compile time.
At runtime an enum is simply a replacement for a certain numeric / primitive value (usually int32). So an enum like this:
public enum MyEnum
{
Cat, Dog, Snake, Cow
}
Just maps those names to integer values:
MyEnum.Cat == 0
MyEnum.Dog == 1
MyEnum.Snake == 2
MyEnum.Cow == 3
Unity's tags are actually string based so what's the point of creating an enum? If you want to display a dropdown for a tag selection in a custom editor, just use the EditorGUILayout.TagField or use the more general EditorGUILayout.Popup which takes the current index and a string array.
Thanks, that's helped a lot.
I now how a dropdown allowing me to select one tag from all available tags.
I've had a look over the doco for both EditorGUILayout.TagField and EditorGUILayout.Popup, and it doesn't look like it's possible to select multiple items from the drop down at once. Are you aware of a way of achieving this?
[CustomEditor(typeof(PointerColliderAction))]
public class PointerColliderEditor : Editor
{
string[] tagStr = UnityEditorInternal.InternalEditorUtility.tags;
int tagIndex = 0;
public override void OnInspectorGUI ()
{
// Draw the default inspector
DrawDefaultInspector();
tagIndex = EditorGUILayout.Popup(tagIndex, tagStr);
EditorUtility.SetDirty(target);
}
}
@hmb3141: A GameObject can only have one tag at a time. It's not possible to select multiple tags. Even when you have an enum that wouldn't change any thing. An enum value also just has a single value. You can't use tags like layers as layers are implemented as a bitmask. Bitmasks are limited to the bit count of the underlying type. Usually 32 bits since and int (int32) as 32 bits. You can have more than 32 tags so there's no way to generally create a bit mask for tag values.
What's actually the point of that? As said: Only one tag can be used at a time.
edit
If you want the user to specify multiple tags you have to store them in an array. When you ask a question it's usually a good idea to describe your whole problem and not just ask a fraction of something you think could be a possible solution.
ps: Why do you call SetDirty every time OnInspectorGUI is called? That would invalidate the scene / asset all the time. You also doesn't seem to edit anything on your target object.
What's actually the point of that? As said: Only one tag can be used at a time.
I'm creating a script that controls a crosshair. I want this script to alter the crosshair (change colour, animate, etc) depending on what my Raycast collides with. For example, check if it collides with an abject with tag "x" || "y" || "z"
I realise it's simpler to do this without accessing the Tags in the inspector at all, however being able to chose the tags from the inspector seemed like a nice addition. Also I thought it may be useful for other situations at some point. Also, I was just curios how it would work.
If you want the user to specify multiple tags you have to store them in an array.
Is this achievable with EditorGUILayout.Popup? Would I have to just have multiple dropdowns?
When you ask a question it's usually a good idea to describe your whole problem and not just ask a fraction of something you think could be a possible solution.
That's a good point, I'll keep this in $$anonymous$$d in future.
ps: Why do you call SetDirty every time OnInspectorGUI is called? That would invalidate the scene / asset all the time. You also doesn't seem to edit anything on your target object.
I just copied and pasted an example of EditorGUILayout.Popup that I found and then altered it to test whether the tags showed in the inspector .
Thanks for your help
Answer by HolBol · Dec 14, 2014 at 12:50 AM
I believe you could simply do this:
enum tags {
tag0 = tagStr[0],
tag1 = tagStr[1]
}
Just replace tag0 etc with what you want each tag to be referred to when you call tags.whatever.
Thanks for your suggestion. It makes sense.
However it's not ideal as
It requires me to manually name the enum values
I want the enum to be dynamic in that when a tag is added to tags, my tags enum will also be updated. I don't want to have to update my enum manually.
I'm trying to create a script which enables me to chose when to call a method based on which tags a ray cast collides with.
Yep only integers of those types:
byte, sbyte, short, ushort, int, uint, long, ulong
However the values of an enum need to be a constant expression as it need to be known at compile time. You can't use a value stored in a variable.