Convert Enums into Array

Godot Version

4.3.rc3

Question

i want an export variable whose values default to the values of an enum. But i don’t know an easy/elegant way to turn the list of enum values into an array to use as the default value. The code:

enum TargetingStrategy {First, Strongest, Random}
@export var allowed_targeting : Array[TargetingStrategy] = ???

Purpose: Most towers can use all 10 targeting strategies but a few can’t. Rather than make them enter which enum values are allowed (since it’s normally all of them), i want to start them with the list and let the exception cases delete values.

In Java or Kotlin i could do something like allowed_targeting = TargetingStrategy.map{it.name}. Something with a loop. i don’t know how to loop over an enum in GDScript.

What exactly is the problem?

i’m looking for a method that can turn an enum into an array of values to use as the default property for an export variable. Something like:

@export var allowed: Array[MyEnum] = MyEnum.values()
or 
    Array.asList(MyEnum)
or even
    MyEnum.map{it}

It should be just this:

enum TargetingStrategy {First, Strongest, Random}
@export var allowed_targeting : Array[TargetingStrategy] = [TargetingStrategy.First, TargetingStrategy.Strongest, TargetingStrategy.Random]

i could do that but it’s a lot of typing (i suppose 10 isn’t a lot but it feels like it) and more importantly as i add new enum values i have to keep both lists in sync. If there’s no programmatic way to do it then i’ll have to resort to hard coding it but before i do i want to see if there’s a more maintainable way.

Yes you can do TargetingStrategy.keys(), but i think in this case it would have to be a @tool-script since you are trying to execute code

2 Likes

Hey @baylorw, maybe u can try do it iterating over your enum and add its value to the var once ready.

Something like:

enum TargetingStrategy {First, Strongest, Random}

@export var allowed_targeting : Array[TargetingStrategy]


func _ready() -> void:
  allowed_targeting = enum_to_array(TargetingStrategy)


func enum_to_array(_enum: Dictionary) -> Array:
	return _enum.values().map(func(key): return key)

Also, here u can see how to iterate over the enum with the map method or u could also do it with a for loop, since that by the end of the day, enums are dictionaries.

1 Like

Maybe export flags would do you better? Though you would need to re-write allowed_targeting code to support the bit-mask int.

@export_flags("First", "Strongest", "Random") var allowed_targetings: int = 0xFFFF
3 Likes

i like the code but the problem is that @export variables behave a little weirdly. i have to initialize the values in the declaration line, can’t do it in _ready(). If this weren’t an export variable this would be a lot easier.

After playing around with a couple of options i think i’ll bite the bullet and just manually specify the values and accept the maintenance burden.

I don’t understand. Why cant you just do this:

enum TargetingStrategy {First=1, Strongest=2, Random=-1}
@export var allowed_targeting = TargetingStrategy

A dictionary is an iterator object just like an array., Then you can iterate as you wish:

	for i in allowed_targeting:
		prints(i, allowed_targeting[i])