- Home /
Creating a SerializedProperty for type
I have an editor script that needs to store and display some data. It should work the same way public variables do for monobehaviours. Normally this could just be done using EditorGUI.SomethingField(something); but in my case, I don't know the type of object that will be stored until runtime.
I know that SerializedProperty can hold any sort of object I need, so I'm trying to use that. Problem is, how can I create a SerializedProperty for a given type? For example, I want to do something like this:
private SerializedProperty property;
private void CreateProperty(Type type)
{
property = new SerializedProperty(type);
}
private void OnGUI()
{
EditorGUILayout.PropertyField(property);
}
There will also need to be some way to actually serialize that property for persistence.
How can something like this be done?
Answer by VesuvianPrime · Aug 02, 2014 at 07:10 PM
Hey Stuffses
Unfortunately you can't store a Type in a SerializedProperty, but you CAN store a string!
/// <summary>
/// Provides util methods for working with Types.
/// </summary>
public static class TypeUtils
{
/// <summary>
/// Converts the input string to a Type.
/// </summary>
/// <returns>The Type.</returns>
/// <param name="typeString">Type string.</param>
public static Type FromString(string typeString)
{
return Type.GetType(typeString);
}
/// <summary>
/// Converts the input Type to a string.
/// </summary>
/// <returns>The string.</returns>
/// <param name="type">Type.</param>
public static string ToString(Type type)
{
return type.AssemblyQualifiedName;
}
}
I guess I can serialize with strings, but how should they be displayed? Right now it seems the only option is this:
if (type == typeof(int))
intValue = EditorGUILayout.IntField(intValue);
else if (type == typeof(float))
floatValue = EditorGUILayout.FloatField(floatValue);
else if (type == typeof(float))
floatValue = EditorGUILayout.FloatField(floatValue);
else if...
Aha, I see what you're doing now. Unfortunately presentation is going to be on a type by type basis here (may I suggest you use a switch?).
I've been writing a GenericAttribute for a similar situation:
using System;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Assets.Scripts
{
/// <summary>
/// Generic attribute provides a way to display object fields for a generic type
/// in the unity inspector.
/// </summary>
[Serializable]
public class GenericAttribute : PropertyAttribute
{
public event EventHandler valueChanged;
#region Properties
[SerializeField] private Object m_Value;
/// <summary>
/// Gets or sets the value.
/// </summary>
/// <value>The value.</value>
public Object value
{
get { return m_Value; }
set
{
if (value == m_Value)
return;
m_Value = value;
OnValueChanged();
}
}
[SerializeField] private string m_ValueTypeString;
/// <summary>
/// Gets or sets the type of the value.
/// </summary>
/// <value>The type of the value.</value>
public Type valueType
{
get
{
return TypeUtils.FromString(m_ValueTypeString);
}
private set
{
m_ValueTypeString = TypeUtils.ToString(value);
}
}
#endregion
/// <summary>
/// Initializes a new instance of the
/// <see cref="GenericAttribute"/> class.
/// </summary>
/// <param name="valueType">Value type.</param>
public GenericAttribute(Type valueType)
{
this.valueType = valueType;
}
/// <summary>
/// Raises the value changed event.
/// </summary>
public void OnValueChanged()
{
EventHandler handler = valueChanged;
if (handler != null)
handler(this, EventArgs.Empty);
}
}
}
I, too, am having trouble figuring out the best way of presenting my data in the inspector.
Have you found a generic was to serialize these objects so they persist across sessions? Primitive types would be fairly easy of course, but what about references to scene objects or prefabs?
It's all marked as serialized, so as long as your fields are serialized it should take care of itself.
Not sure how well it works with prefabs. I've been doing Unity stuff for a few years now and the linking of prefabs is still a mystery to me. Best bet is to try it and see what happens!
Your answer
Follow this Question
Related Questions
OnSerialize event 2 Answers