Enum-like SharedVariable

srgfraser

New member
I'm trying to implement a Shared Variable very similar to a dynamic enum (which don't exist as far as I know).

Basically, I would like to implement a dropdown to select a value from, just like you would with a Shared Variable created from an enum, but I need to build the contents of the dropdown from the Owner's internal workings which are not static.

I know you can create selectable lists dynamically. I see them with things like Game Objects, and scriptable Objects. But instead of querying Unity, I would just like to create, let's say a list Key Value pairs and then created the selectable dropdown from them.

Clear as mud?

Hopefully, thanks in advance.
 
At the end of the day you are saving an int value, correct? And it's just the display that you want to change?

There isn't anything like this built-in, but you could create a new ObjectDrawer for your modified SharedInt. This will allow you to draw whatever objects you want within the dropdown.

 
Last edited:
Thanks for the helpful direction. Here is what I ended up with. It's a bit more elaborate than the original question. This code actually has 2 dropdowns the second based on the results of the first. I didn't include the code for the creation of the option dropdown arrays but they basically just build arrays of strings based on the internal workings of a class called MAnimal.

(BTW... I think I oops and removed the resolved flag and I don't know how to restore it)

C#:
    public override void OnGUI(GUIContent label)
    {
        if (value is not SpeedState mSpeed)
            return;

        if (task != null && task.Owner != null)
        {
            if (!task.Owner.gameObject.TryGetComponent<MAnimal>(out var animal))
                return;

            var tSpeedSets = GetSpeedSetNames(animal);
            var speedSetIndex = string.IsNullOrEmpty(mSpeed.speedSet) ? 0 : tSpeedSets.FindIndex(s => s == mSpeed.speedSet);
            var speedSetOptions = tSpeedSets.ToArray();

            var tSpeeds = GetSpeedNames(animal, speedSetOptions[speedSetIndex]);
            var speedIndex = string.IsNullOrEmpty(mSpeed.speed) ? 0 : tSpeeds.FindIndex(s => s == mSpeed.speed);
            var speedOptions = tSpeeds.ToArray();

            EditorGUILayout.BeginVertical();
            {
                EditorGUI.BeginChangeCheck();
                speedSetIndex = EditorGUILayout.Popup("Speed Set", speedSetIndex, speedSetOptions);

                if (EditorGUI.EndChangeCheck())
                {
                    var speeds = GetSpeedNames(animal, speedSetOptions[speedSetIndex]);
                    speedIndex = 0;
                    speedOptions = speeds.ToArray();
                }

                speedIndex = EditorGUILayout.Popup("Speed", speedIndex, speedOptions);

                mSpeed.speedSet = speedSetOptions[speedSetIndex];
                mSpeed.speed = speedOptions[speedIndex];
            }
            EditorGUILayout.EndVertical();
        }

        value = mSpeed;
    }

Note I made a small edit to the code to check for task.Owner != null. If you don't you get an error stating the BehaviorTree is still in use when you stop the application.
 
Last edited:
Back
Top