- Home /
Unable to serialize my list in a Unity Custom Editor script.
I'm trying to serialize my list from my custom Unity Editor script so that it doesn't revert to prefab as soon as I press Play. The list contains Waypoints that can be added in the editor. I have a function that iterates through the waypoint list, increments its size, and adds the new waypoint to the end of the list.
void SetWaypointToEndOfList (Waypoint w) {
if(waypointsProp.isArray) {
int arrayLength = 0;
waypointsProp.Next(true); // skip generic field
waypointsProp.Next(true); // advance to array size field
arrayLength = waypointsProp.intValue; // Get the array size
waypointsProp.Next(true); // advance to first array index
waypointsProp.arraySize++;
arrayLength++;
int lastIndex = arrayLength - 1;
for(int i = 0; i < arrayLength; i++) {
if(i < lastIndex) waypointsProp.Next(false); // advance without drilling into children
else waypointsProp.objectReferenceValue = w;
}
waypointsProp = serializedObject.FindProperty ("waypoints"); //Resetting the property so that the array index is reset.
}
}
The problem occurs as soon as the compiler reaches this line: "waypointsProp.objectReferenceValue = w;"
I get this error message: "type is not a supported pptr value". Manually casting it as an object doesn't work.
By the way, the Waypoint script is a Monobehaviour, not a ScriptableObject. I can't make it a ScriptableObject because ScriptableObjects cannot be attached to GameObjects, and these waypoints need to be objects in the scene. Unless there is a way to make ScriptableObjects that are attachable to GameObjects? Or Monobehaviours that are serializable?
Answer by vexe · Apr 21, 2014 at 09:02 AM
waypointsProp.objectReferenceValue = w;
To me this looks like setting the array reference itself to the waypoint value? if Waypoint
is a MonoBehaviour then you should have no problems adding one to your list. I never used that Next
method... (BTW I usually get the "type is not a supported pptr value" error when I try to assign the objectReferenceValue
to a System.Object that's not a UnityEngine.Object
)
I use extensions for that:
using sp = UnityEditor.SerializedProperty;
using UnityEditor;
using UnityEngine;
public static class SerializedPropertyExtensions
{
public static void Add(this sp prop, Object value)
{
prop.arraySize++;
prop.GetAt(prop.arraySize - 1).objectReferenceValue = value;
}
public static sp GetAt(this sp prop, int i)
{
return prop.GetArrayElementAtIndex(i);
}
public static void SetObjectValueAt(this sp prop, int i, System.Object toValue)
{
prop.GetAt(i).SetObjectValue(toValue);
}
public static void SetObjectValue(this sp prop, System.Object toValue)
{
switch (prop.propertyType) {
case SerializedPropertyType.Boolean:
prop.boolValue = (bool)toValue;
break;
case SerializedPropertyType.Bounds:
prop.boundsValue = (Bounds)toValue;
break;
case SerializedPropertyType.Color:
prop.colorValue = (Color)toValue;
break;
case SerializedPropertyType.Float:
prop.floatValue = (float)toValue;
break;
case SerializedPropertyType.Integer:
prop.intValue = (int)toValue;
break;
case SerializedPropertyType.ObjectReference:
prop.objectReferenceValue = toValue as UnityEngine.Object;
break;
case SerializedPropertyType.Rect:
prop.rectValue = (Rect)toValue;
break;
case SerializedPropertyType.String:
prop.stringValue = (string)toValue;
break;
case SerializedPropertyType.Vector2:
prop.vector2Value = (Vector2)toValue;
break;
case SerializedPropertyType.Vector3:
prop.vector3Value = (Vector3)toValue;
break;
}
}
}
Unless there is a way to make ScriptableObjects that are attachable to GameObjects?
The point of ScriptableObjects
is that they're classes that you could use to hold data without having to attach them to a GameObject
- The dif between them and regular classes (that inherit directly from System.Object) is that SO play better with Unity's serialization system, than a regular C# class (I rarely use SOs TBH...)
Or Monobehaviours that are serializable?
All UnityEngine.Objects
are serializable by Unity by default (with some conditions, for ex the ref has to be public non-static, or non-public non-static mocked with SerializeField
... See this for more details)
Wow, thanks! This solved my issue and was extremely informative :D