原文地址:https://blog.csdn.net/qq_35361471/article/details/84715491
原文地址:https://blog.csdn.net/tom_221x/article/details/79437561
序列化相关问题:https://blog.uwa4d.com/archives/2025.html
一直想研究,怎么使用 ScriptableObject 来存储多态数组,目前U3d 中序列化是不允许的。
第一种尝试
思想:把多态类型的基类继承自ScriptableObject ,然后属性面板界面自己实现:
[Serializable]
public class StoryEffect:ScriptableObject
{
protected string _Name = "StoryEffect";
protected string _EffectBasePath = "StoryNode/StoryCanvas/";
[SerializeField]
protected StorySegment.StoryState _ExecState = StorySegment.StoryState.NONE;
private bool _IsPlaying = false;
public bool IsPlaying {
get { return _IsPlaying; }
}
public StorySegment.StoryState ExecState
{
get { return _ExecState; }
}
public string Name
{
get { return _Name; }
}
public virtual IEnumerator Init()
{
Debug.Log("StoryEffect:Init______________________");
yield return null;
}
public virtual IEnumerator Play()
{
Debug.Log("StoryEffect:Play______________________");
_IsPlaying = true;
yield return null;
}
}
public class StorySegment : ScriptableObject,IStorySegment
{
public enum StoryState
{
NONE = 0,
START = 1,
DOING = 2,
END = 3,
}
[SerializeField]
private int _ID = 0;
[SerializeField]
private List<StoryEffect> _StoryEffectList = new List<StoryEffect>();
private StoryState _CurState = StoryState.NONE;
private bool _IsEnd = false;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
// 绘制全部原有属性
//base.DrawDefaultInspector();
//重绘数组界面
EditorGUILayout.PropertyField(this.serializedObject.FindProperty("_ID"), true);
_expand = EditorGUILayout.Foldout(_expand, "StoryEffectList");
if (_expand)
{
EditorGUI.indentLevel++;
for (int i = 0; i < _target.GetStoryEffectCount(); ++i)
{
var ttt = _target.GetStoryEffectByIndex(i);
var subopen = false;
if (!_subExpand.TryGetValue(i, out subopen))
{
subopen = false;
}
GUILayout.BeginHorizontal();
if (GUILayout.Button("删", GUILayout.Width(20), GUILayout.Height(20)))
{
_target.RemoveStoryEffectByIndex(i);
return;
}
_subExpand[i] = EditorGUILayout.Foldout(subopen, ttt.Name);
GUILayout.EndHorizontal();
if (subopen)
{
EditorGUI.indentLevel++;
Type t = ttt.GetType();
FieldInfo[] fieldInfos = t.GetFields(BindingFlags.Instance|BindingFlags.Static | BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Default);
//Debug.Log("fieldName------>" +fieldInfos.Length);
PropertyInfo[] ps = t.GetProperties(BindingFlags.Instance|BindingFlags.Static | BindingFlags.Public|BindingFlags.DeclaredOnly);
foreach (var p in ps)
{
string pName = p.Name;
string pType = p.PropertyType.ToString();
object pValue = p.GetValue(ttt,null);
if (p.CanWrite)
{
DisStoryEffectPropertyInfo(pName, pType, pValue, p, ttt);
}
}
foreach (var f in fieldInfos)
{
//字段名称
string fieldName = f.Name;
//字段类型
string fieldType = f.FieldType.ToString();
//字段的值
object fieldValue = f.GetValue(ttt);
if (f.GetCustomAttributes(typeof(SerializeField), true).Length > 0)
{
DisStoryEffectFieldInfo(fieldName, fieldType, fieldValue, f, ttt);
}
// Debug.Log("fieldName------>" + field