表示数组、列表、结构体或类。
Generic 类型用于内联序列化的复合类型
- 数组和列表。
- 用户定义的结构体(例如,不是内置的 Unity 类型)。
- 按值序列化的类(例如,在没有 SerializeReference 属性的情况下引用)。
- 一些内置的 Unity 结构体,当它们没有专门的 SerializedPropertyType 枚举值时。例如 RectOffset 是 Generic,但 Vector3 是 SerializedPropertyType.Vector3。
注意:当用作 SerializedProperty 类型时,术语 Generic 不应与无关的 C# 特性(泛型类和方法)混淆。
其他资源:SerializedProperty.isArray、SerializedPropertyType.ManagedReference、SerializedPropertyType.ObjectReference
using System; using System.Text; using UnityEngine; using UnityEditor; using System.Collections.Generic;
namespace GenericObjectTypeExample { [Serializable] public struct ExampleStruct { public int m_Field; };
[Serializable] public class ExampleClass { public int m_Field; };
public class GenericTypeExample : ScriptableObject { // All these fields will be serialized public int[] m_ArrayOfInt; public List<int> m_ListOfInt; public ExampleStruct m_ExampleStruct = new ExampleStruct() { m_Field = 1 }; public ExampleClass m_ExampleClass = new ExampleClass() { m_Field = 2 };
[SerializeReference] public ExampleClass m_ManagedClass = new ExampleClass() { m_Field = 3 };
[MenuItem("Example/SerializedPropertyType Generic Example")] static void GenericExample() { var scriptableObject = ScriptableObject.CreateInstance<GenericTypeExample>(); using (var serializedObject = new SerializedObject(scriptableObject)) { var report = new StringBuilder();
// Generic ReportType(report, serializedObject, "m_ArrayOfInt"); ReportType(report, serializedObject, "m_ListOfInt"); ReportType(report, serializedObject, "m_ExampleStruct"); ReportType(report, serializedObject, "m_ExampleClass");
// Not Generic ReportType(report, serializedObject, "m_ManagedClass");
Debug.Log(report.ToString());
AccessGenericValues(serializedObject); } }
static void AccessGenericValues(SerializedObject serializedObject) { // "generic" type struct and objects can be retrieved directly with boxedValue ExampleStruct structValues = (ExampleStruct)serializedObject.FindProperty("m_ExampleStruct").boxedValue;
// Alternatively individual fields can be read int fieldInStruct = serializedObject.FindProperty("m_ExampleStruct.m_Field").intValue;
Debug.Log($"Value of field in struct: {structValues.m_Field}, Value of field direct read: {fieldInStruct}");
// Similarly boxedValue supports writing to an inline class SerializedProperty inlineClass = serializedObject.FindProperty("m_ExampleClass");
// Serialize new state in a single call inlineClass.boxedValue = new ExampleClass() { m_Field = 4 };
// Individual fields can also be accessed Debug.Log($"Value of field in class after write: {inlineClass.FindPropertyRelative("m_Field").intValue}");
serializedObject.ApplyModifiedProperties(); }
static void ReportType(StringBuilder report, SerializedObject serializedObject, string propertyPath) { var serializedProperty = serializedObject.FindProperty(propertyPath); report.AppendLine($"{propertyPath} has type {serializedProperty.propertyType}"); } } }