- Home /
How to work with custom class (ScriptableObject) SerializedProperty?
Hello, im trying to make customclasses that are derived from ScriptableObject work with SerializedProperty
Below, i have made a very minimal and simple example that works without deriving from ScriptableObject.
Human.cs
public class Human : MonoBehaviour
{
public Weapon Weapon;
public int Health;
}
Weapon.cs
[System.Serializable]
public class Weapon
{
public int Damage;
public int Weight;
}
HumanEditor.cs
[CustomEditor(typeof(Human))]
public class HumanEditor : Editor
{
SerializedObject sObj;
void OnEnable()
{
this.sObj = new SerializedObject(target);
Weapon weapon = ((Human)target).Weapon;
if (weapon == null)
weapon = new Weapon();
}
public override void OnInspectorGUI()
{
this.sObj.Update();
SerializedProperty sHealth = sObj.FindProperty("Health");
sHealth.intValue = EditorGUILayout.IntField("Health", sHealth.intValue);
SerializedProperty sWeaponDamage = sObj.FindProperty("Weapon.Damage");
sWeaponDamage.intValue = EditorGUILayout.IntField("Damage", sWeaponDamage.intValue);
SerializedProperty sWeaponWeight = sObj.FindProperty("Weapon.Weight");
sWeaponWeight.intValue = EditorGUILayout.IntField("Weight", sWeaponWeight.intValue);
this.sObj.ApplyModifiedProperties();
}
}
This works. But when i derived weapon from ScriptableObject, and change the OnEnable() function to:
void OnEnable()
{
this.sObj = new SerializedObject(target);
SerializedProperty sWeapon = sObj.FindProperty("Weapon");
if (sWeapon.objectReferenceValue == null)
sWeapon.objectReferenceValue = ScriptableObject.CreateInstance<Weapon>();
}
Then i get an exepction saying its null. What should i do to make it work with ScriptableObject? The reason i need this, is because i want to use polymorphism and inheritance with Weapon.
Answer by frarees · Oct 11, 2014 at 02:18 PM
ScriptableObjects need to have an asset representation. So, you need to save the instance somewhere (e.g. save as subasset):
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(Human))]
public class HumanEditor : Editor {
void OnEnable () {
serializedObject.Update ();
SerializedProperty serializedWeapon = serializedObject.FindProperty ("Weapon");
if (serializedWeapon.objectReferenceValue == null) {
Weapon w = ScriptableObject.CreateInstance<Weapon> ();
// You can configure w.hideFlags here wisely
AssetDatabase.AddObjectToAsset (w, target);
serializedWeapon.objectReferenceValue = w;
}
serializedObject.ApplyModifiedProperties ();
}
public override void OnInspectorGUI () {
serializedObject.Update ();
SerializedProperty health = serializedObject.FindProperty ("Health");
health.intValue = EditorGUILayout.IntField ("Health", health.intValue);
SerializedObject weaponSerializedObject = new SerializedObject (serializedObject.FindProperty ("Weapon").objectReferenceValue);
weaponSerializedObject.Update ();
SerializedProperty weaponDamage = weaponSerializedObject.FindProperty ("Damage");
weaponDamage.intValue = EditorGUILayout.IntField ("Damage", weaponDamage.intValue);
SerializedProperty weaponWeight = weaponSerializedObject.FindProperty ("Weight");
weaponWeight.intValue = EditorGUILayout.IntField ("Weight", weaponWeight.intValue);
weaponSerializedObject.ApplyModifiedProperties ();
serializedObject.ApplyModifiedProperties();
}
}
About inheritance and polymorphism, you should look at this.
Yes, i have done it in the OnInspectorGUI, but i just tried in the OnEnable(), and it still doesn't work :/
But thanks for answering and giving me the link
Your answer
Follow this Question
Related Questions
Dynamic serialized fields based on enum 0 Answers
How do I associate my custom object for the serializedProperty objectReferenceValue 1 Answer
What would be the best way to go about loading and saving a Serializable object in JSON with Unity? 0 Answers
[Solved]Why doesn't my ScriptableObject based asset save using a custom inspector ? 1 Answer