[Solved] Choosing a class attribute from the inspector?

I’m a trying to make a ScriptableObject that outlines a buff for the stats of a character. That looks about like this:

public class StatBuff : StatusEffect {

    public int buffStrength;

    public override void ApplyEffect(Character character) {
        character.GetStats().stamina.AddModifier(buffStrength);
    }

    public override void EndEffect(Character character) {
        character.GetStats().stamina.RemoveModifier(buffStrength);
    }
}

The GetStats() method returns the character’s instance of the CharacterStats class, which defines which stats a character should have.

I want to be able to choose which stat from the CharacterStats class (stamina being an example) I would like to buff from the inspector, so that I don’t have to make a different ScriptableObject for each stat in the CharacterStats class. I would imagine this would involve getting the attributes/fields of the CharacterStats class and listing them in a drop box, but I do not know how to do this. I was thinking this might involve creating a custom editor for the StatBuff class, but I have very little experience writing custom editors. How might I do this? Do I need to use a custom editor?

Thanks in advance. :slight_smile:

So, I think I may have been overthinking things a bit. I realized there wasn’t a need for a custom editor (even though perhaps one could provide a more elegant solution, I don’t know). Honestly, I like the simplicity of my solution anyways.

I ended up solving my problem by creating an enum and a serialized class. The enum contains all of the stats (such as stamina, agility, etc.) and the class just has two fields the stat I want to buff and the strength of said buff. This allows me to simply have an public array of the Buff class in my StatBuff ScriptableObject.

After that I created a helper method that just contained a switch statement for each of my stats and would call the AddModifier method from the Stat class.

This is an example of what some of my code ended up looking like:

public class StatBuff : StatusEffect {

    public Buff[] buffs;

    public override void ApplyEffect(Character character) {
        CharacterStats.AddModifiers(character.GetStats(), buffs);
    }

    public override void EndEffect(Character character) {
        CharacterStats.RemoveModifiers(character.GetStats(), buffs);    
    }
}

Helper Reference Types + Method:

public enum Attribute { Strength, Agility, Intellect, Stamina };

[System.Serializable] // You need this so your class will show up in the inspector
public class Buff {
    [SerializeField]
    private Attribute attribute;
    [SerializeField]
    private int strength;

    public Attribute GetAttribute() {
        return attribute;
    }

    public int GetStrength() {
        return strength;
    }
}
public static void AddModifier(CharacterStats stats, Attribute attribute, int modifierStrength) {
        switch (attribute) {
            case Attribute.Stamina:
                stats.strength.AddModifier(modifierStrength);
                break;
            case Attribute.Agility:
                stats.agility.AddModifier(modifierStrength);
                break;
             // etc....
             default:
                 break;
         }
}

public static void AddModifier(CharacterStats stats, Buff buff) {
        AddModifier(stats, buff.GetAttribute(), buff.GetStrength());
}

I think that the code in the helper method could use some simplifying, as there’s probably a more elegant solution as opposed to just using a switch statement (which will need to be updated along with the enum if stats are added or removed). It’ll do for now. I hope this helps anyone who Googles something like this, so they can realize the problem was really quite simple and they were just over thinking it like I was.

Cool, nicely done :slight_smile:

Problem solving is good fun.