Initialize Array with Property Attribute

I’ve done something that works, but I wonder if it is the best way to do it?

I’ve created a class Stat.cs

[System.Serializable]
public class Stat {

    // Base Value
    public float BaseValue;

    // Used by StatAttribute to know if stat default value has been set
    [SerializeField]
    [HideInInspector]
    private bool m_statAttributeInitialized = false;

    public Stat()
    {
         BaseValue = 0f;        
    }
    public Stat(float _startingValue)
    {
        BaseValue = _startingValue;
    }
}

So I could basically have something like

public Stat Health = new Stat(100);

to set the default health of my character to 100;

Where this get a bit trickier, is that I also use that class as a modifier. A character as a list of Damage modifier base on the damage type (let say fire, cold, lightning, physical, etc.)
So I have this:

public Stat[] DamageTypesModifier = new Stat[(int)DamageType.Types.Count];

But I want each stat to be initialized with a BaseValue = 1. I didn’t want to create an editor script for my Character.cs just for that array. I could also want to initialize other Stat array in various class and making an editor script for each of them would be annoying.

So I created an StatAttribute.cs

public class StatAttribute : PropertyAttribute
{
    public readonly float BaseValue;

    public StatAttribute(float _baseValue)
    {
        this.BaseValue = _baseValue;
    }

}

and an associated drawer. Basically, it checks if my init flag is true, if not, it sets the BaseValue.

[CustomPropertyDrawer(typeof(StatAttribute))]
public class StatAttributeDrawer : PropertyDrawer
{

    StatAttribute statAttribute { get { return ((StatAttribute)attribute); } }

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        SerializedProperty baseVal = property.FindPropertyRelative("BaseValue");
        SerializedProperty init = property.FindPropertyRelative("m_statAttributeInitialized");

        if (!init.boolValue)
        {
            init.boolValue = true;
            baseVal.floatValue = statAttribute.BaseValue;
        }

        EditorGUI.BeginProperty(position, label, property);

        baseVal.floatValue = EditorGUI.FloatField(position, label, baseVal.floatValue);

        EditorGUI.EndProperty();
    }
}

Now I can do this, and they will all be set to 1 by default. I can also edit them before/during runtime without having the default value being set each time.

[Stat(1f)]
public Stat[] DamageTypesModifier = new Stat[(int)DamageType.Types.Count];

This avoided me to create a StatModifier class that only override Stat class with a default constructor that set BaseValue =1; This can also be used to initialize a Stat array with another value than 1.

Is there a better way to do this?

You may want to use System.Collections & System.Linq.

using System.Collections;
using System.Linq;

public class HostClass{
    public State[] states = Enumerable.Range(0, 10).Select(i => new State(1f)).ToArray();
}