- Home /
How can I correctly draw properties instead of fields in a custom property drawer?
Right now I can get the backing fields for my properties to draw nicely when referenced by the property drawer, which is something of a workaround, but my problem is that I'm using property getters and setters to calculate the values I want displayed. As such nothing updates in the editor until the property's getter sorts things out the next time the property's value is called for.
There are plenty of bodged ways I can think of to get round this, but none of them seem very elegant when really the only reason I wanted the custom property drawer is to make everything tidier, not worse. I figured I could just treat the property like a field and use it directly in the property drawer, but that one's throwing a null reference exception at me.
What am I doing wrong?
Although not strictly integral to the issue, I've incuded my Stat class and its custom property drawer in hopes that people can better see what my issue is and what I'm trying to do. In matters of property drawers I have no idea what I'm doing half the time, so apologies if it's something blatantly obvious.
using UnityEngine;
[System.Serializable]
public class Stat
{
[SerializeField] float character = 0f;
public float Character
{
get
{
return character;
}
set
{
if (value > 100f)
{
character = 100f;
}
else if (value < 0f)
{
character = 0f;
}
else
{
character = value;
}
Character = character;
}
}
[SerializeField] float rangeMin = 0f;
[SerializeField] float rangeMax = 100f;
public float modifier;
[SerializeField] float effective = 0f;
public float Effective
{
get
{
effective = rangeMin + (((rangeMax - rangeMin) / 100) * (Character + modifier));
if (effective < 0f)
{
effective = 0f;
}
return effective;
}
}
}
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(Stat))]
public class StatPD : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
SerializedProperty character = property.FindPropertyRelative("character");
SerializedProperty rangeMin = property.FindPropertyRelative("rangeMin");
SerializedProperty rangeMax = property.FindPropertyRelative("rangeMax");
SerializedProperty modifier = property.FindPropertyRelative("modifier");
SerializedProperty effective = property.FindPropertyRelative("effective");
Rect rectTitle = new Rect(position.x, position.y, 85, 20);
Rect rectEffectiveValue = new Rect(position.x + rectTitle.width, position.y, 50, 20);
Rect rectCharacterBar = new Rect(position.x + rectTitle.width + rectEffectiveValue.width, position.y, position.width - (rectTitle.width + rectEffectiveValue.width), 20);
Rect rectEffectiveBar = new Rect(position.x, position.y + 20, position.width, 20);
Rect rectModifier = new Rect(position.x - 20, position.y + 20, 120, 20);
GUI.Label(rectTitle, property.displayName, EditorStyles.boldLabel);
character.floatValue = EditorGUI.Slider(rectCharacterBar, character.floatValue, 0, 100);
if (modifier.floatValue > 0)
EditorGUI.LabelField(rectModifier, "+" + modifier.floatValue.ToString());
else if (modifier.floatValue < 0)
EditorGUI.LabelField(rectModifier, modifier.floatValue.ToString());
EditorGUI.ProgressBar(rectEffectiveBar, effective.floatValue / 100, rangeMin.floatValue.ToString() + " - " + rangeMax.floatValue.ToString());
EditorGUI.LabelField(rectEffectiveValue, effective.floatValue.ToString("##0.00"), EditorStyles.boldLabel);
}
Your answer
Follow this Question
Related Questions
Caching data for a PropertyDrawer 1 Answer
How can I show tooltip on property field? 4 Answers
Accessing properties with spaces? 1 Answer
Properties names, same as class okay or bad? 1 Answer
PropertyDrawer dynamic subdrawer 0 Answers