- Home /
Using SerializedProperty on custom classes?
I have tried for a while now to get the SerializedProperty to work on my own custom classes, but have so far been unsuccessful. Basic values works fine(bool, int, string etc), but when I try to get the custom ones the challenge begins. I have tried using the objectReferenceValue on an object that extends ScriptableObject, but this for some reason does not seem to work on multiple objects.
Example: I've tried this, and it somehow seems to work with a single object, but only affect one object if multiple is selected.
((MyClass)swipeSound.objectReferenceValue).MyFunction();
((MyClass)swipeSound.objectReferenceValue).myCustomVariable = myCustomVariable;
And would it be possible to convert a SerializedProperty to the actual type without using the ScriptableObject as a base class, something like this:
MyEnum myEnum =((MyEnum)serializedProperty);
I was wondering if anyone have any experience with the SerializedObject/SerializedProperty variables and might have any suggestions to how to overcome these challenges?
I was running into a similar issue where I could only serialize primitive types, and someone suggested looking into ISerializationSurrogate and that ended up working for me. I am now able to serialize GameObject references, Vector3 etc etc. http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializationsurrogate.aspx
Ah, and here is a good example of how you'd use it: http://msdn.microsoft.com/en-us/magazine/cc188950.aspx
Thanks for the information, I'll take a closer look at it and see if it's what I need. :D
scriptable object is a standalone class. If you want it to be saved, it need to be an asset as well. If you don't want it to be an actual assetm use "normal" serializable data classes. Unity's serialization works way different to C# serialization.
The only objects that can (truly) be serialized are unity'S buildin objects which derives from UnityEngin.Object. Pure data-classes aren't serialized the same way. If a $$anonymous$$onoBehaviour or a ScriptableObject has such a data class as member, it is serialized along with the $$anonymous$$onoBehaviour / ScriptableObject. Each of the buildin classes are serialized on their own. $$anonymous$$onoBehaviours are serialized in a prefab sinc they are attached to gameobject. Scriptable objects are on their own. If you need them as asset, save them as asset, like the Terrain for example
Answer by dylanfries · Jun 29, 2012 at 01:24 PM
To write an editor class that uses SerializableProperty's to access values from the inspector, the class you're trying to reference should 1) Extend ScriptableObject ( which you've done) 2) Have all its variables be individually serializable ( which most unity types are by default and custom classes can be with some work)
It is possible to have a List in a single SerializableProperty though, as long as everything in that List is itself serializable. To build an editor class that is directly associated with a non-editor class, I believe the non-editor class has to be serializable, or at least the variables you are trying to access have to be serializable. Then you can grab a reference to that class using
SerializedObject object;
OnEnable(){
object = new SerializedObject(target); // target is
}
You may also need
[CustomEditor (typeof(ClassYouAreBuildingAnEditorFor))]
at the top of your file (after using declarations but before your main function) - this will open up the target variable used above, which will be a reference to your ClassYouAreBuildingAnEditorFor
To access properties from this class you can use
SerializableProperty prop = object.FindProperty("propertyName");
I think you've gotten this far on your own. As for lists, you can use List as long as T is a serializable object. This could be int's, float, etc or could be a full custom class that is serializable. It's a bit tricky to access this, but you can use
SerializableProperty list = object.FindProperty("ListOfSerializableObjects");
SerializableProperty listItem = list.GetArrayElementAtIndex(i)) ;
To get or set values of SerializableProperty items, you can use
item.floatValue // for floats
item.objectReferenceValue // for objects
Keep in mind you can iterate serialized lists (they are type IEnumerator) and if you're using basic arrays theres a number of helper functions you can call from SerializedProperty.
Theres a number of other things to do, as the objects are stored as type SerializableObject not as their original type, but I would recommend watching the Intro to Editor Scripting video from Unite 2011 Linked here as that was helpful for me, and likely more accurate. It's a little complicated but once you get the hang of which objects are which type and how to access those, its not too bad. Look at the script documentation for SerializableObject and SerializableProperty as well. Best of luck and I hope this helps.
Sure, I'm trying to use SerializedProperty in an editor class to store values from the base class. This in itself isn't really a problem, where my real challenge begins is when I try to access Lists/Arrays or enums or functions from a none ScriptableObject(if it's even possible).
Enums:
//How do I get the Enum value from the SerializedProperty?
$$anonymous$$yEnum myEnum = someSerializedProperty.; or someSerializedPropertyWithList.GetArrayElementAtIndex(0). none basic value/>;
$$anonymous$$aybe I've misunderstood how the SerializedProperty should be used so all help and directions would be greatly appreciated. :)
Thanks a lot! Exactly what I was looking for for ages.
Answer by caLLow · May 23, 2014 at 06:54 PM
Below is a C# function call for the editor to display child properties of a serialized property.
Usage:
public override void OnInspectorGUI() {
string propertyName = "speed";
SerializedProperty sp = serializedObject.FindProperty(propertyName);
while (sp.Next(true)){
ShowRelativeProperty(sp, "min");
ShowRelativeProperty(sp, "max");
}
}
// Show child property of parent serializedProperty
void ShowRelativeProperty(SerializedProperty serializedProperty, string propertyName)
{
SerializedProperty property = serializedProperty.FindPropertyRelative(propertyName);
if (property != null)
{
EditorGUI.indentLevel++;
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(property, true);
if (EditorGUI.EndChangeCheck())
serializedObject.ApplyModifiedProperties();
EditorGUIUtility.LookLikeControls();
EditorGUI.indentLevel--;
}
}