Problem with PropertyInfo.SetValue

Hello everyone! I have been working on a problem for a while and I was hoping one of you might enlighten me.

I am aware that this might be a problem in my C# logic and not a Unity specific problem, but it could also be related to Unity’s serialization.

So basically I have this Custom Editor script :

[Serializable]
[CustomEditor(typeof(BaseCharacter))]
public class CharacterEditor : Editor {

    public bool affinitysFoldout = false;
    public BaseCharacter _target ;

    public void OnEnable()
    {
        _target = target as BaseCharacter;
    }

    public override void OnInspectorGUI()
    {
        FieldInfo[] fields =  _target.GetType().GetFields();
        EditorGUILayout.Space();
        foreach(FieldInfo info in fields)
        {
            if((typeof(BaseStatGroup)).IsAssignableFrom(info.FieldType))
            {
                BaseStatGroup statGroup = (BaseStatGroup) info.GetValue(_target);
                affinitysFoldout = EditorGUILayout.Foldout(affinitysFoldout, info.Name);
                if (affinitysFoldout) {
                    FieldInfo[] statFields =  info.FieldType.GetFields();
                    foreach(FieldInfo statInfo in statFields)
                    {
                        if (statInfo.FieldType == typeof(AffinityStatistic))
                        {
                            EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
                            EditorGUILayout.BeginVertical(GUILayout.MaxWidth(150));
                            EditorGUILayout.LabelField(statInfo.Name.Replace("_"," "),GUILayout.MaxWidth(100));
                            EditorGUILayout.EndVertical();
                            AffinityStatistic stat = (AffinityStatistic) statInfo.GetValue(statGroup);
                            PropertyInfo[] propertyFields = stat.GetType().GetProperties();
                            foreach(PropertyInfo propertyInfo in propertyFields)
                            {
                                if(propertyInfo.PropertyType == typeof(System.Single))
                                {
                                    EditorGUILayout.BeginVertical();
                                    EditorGUILayout.LabelField(propertyInfo.Name,GUILayout.Width(200));
                                    float f = (float)propertyInfo.GetValue(stat,null);
                                    float ff = EditorGUILayout.FloatField(f,GUILayout.MaxWidth(40));
                                    if (ff!=f)
                                    {
                                        propertyInfo.SetValue(stat, ff,null);
                                        Debug.Log (ff + " AND " +(float)propertyInfo.GetValue(stat,null));
                                    }
                                    EditorGUILayout.EndVertical();
                                }
                            }
                            EditorGUILayout.EndHorizontal();
                        }
                    }
                }
            }
        }
    }
}

Sorry if its a bit long and not very minimized, but I think it’s needed for you to understand the problem. Now this is the BaseCharacter class overriden by the custom editor script

public class BaseCharacter : MonoBehaviour {

    private float life = 0;
    private float mana = -1;


    public AffinityStatGroup Affinitys = new AffinityStatGroup();

    public float Life {
        get {
            return life;
        }
    }

    public float Mana {
        get {
            return mana;
        }
    }

The AffinityStatGroup class along with its base class :

[Serializable]
public class AffinityStatGroup : BaseStatGroup {

    [SerializeField]
    public AffinityStatistic Fire_Affinity = new AffinityStatistic(ElementalType.Fire);

    [SerializeField]
    public AffinityStatistic Water_Affinity = new AffinityStatistic(ElementalType.Water);

    [SerializeField]
    public AffinityStatistic Grass_Affinity = new AffinityStatistic(ElementalType.Grass);


}

[Serializable]
public class BaseStatGroup {

}

And finally, the AffinityStatistic class which derives from BaseStatistic :

[Serializable]
public class AffinityStatistic : BaseStatistic {
}

[Serializable]
public class BaseStatistic  {

    [SerializeField]
    private float value = 0;

    public float Value {
        get {
            return value;
        }
        set {
            value = value;
        }
    }
}

And this is my output :

http://postimg.org/image/r3ef59xd7/

In the first code snippet, what I am trying to do is iterate through (BaseCharacter → Affinitys → Fire_Affinity → Value) using Reflection, and set the Value property with the Inspector. If I change the float field in the inspector, as soon as I unselect it it goes back to 0, indicating that it did not save. In this debug.Log :

 propertyInfo.SetValue(stat, ff,null);
Debug.Log (ff + " AND " +(float)propertyInfo.GetValue(stat,null));

the GetValue always output 0 right after the SetValue when changed, which is weird…

The code successfully goes through the Property Value however, as seen in the debugger.

I am at a loss with this one, I could use some help from some of the smart people around here :slight_smile:

bump

bump

bump