最近在写行为树编辑器 数据存储用到ScriptableObject在制作过程中 对于ScriptableObject遇到一个棘手的问题 下面总结下:
ScriptableObject类无法直接聚合ScriptableObject
例如:
public class Blackboard: ScriptableObject{ }
public class BehaviourTree: ScriptableObject
{
[SerializeField]
public Blackboard board;
public void Init(){
this.board=new Blackboard();
//(或者:this.board=ScriptableObject.CreateInstance<Blackboard>())
}
}
这种写法Create 出来的BehaviourTree asset 的 board 等于null
问题来了 应该如何嵌套类 有二种方式:
第一种是最简单的:
Blackboard类不要继承ScriptableObject,在Blackboard类上加上[System.Serializable] 特性
注意 Blackboard 不能是抽象类。
第二种相对复杂点:
Blackboard依然继承ScriptableObject.
代码片段:
BehaviourTree tree = ScriptableObject.CreateInstance<BehaviourTree>();
AssetDatabase.CreateAsset(tree, "Assets/NewBehaviourTree.asset");
Blackboard blackboard= ScriptableObject.CreateInstance< Blackboard >()
if (EditorUtility.IsPersistent(tree))
{
AssetDatabase.AddObjectToAsset(blackboard,tree);
}
tree. board =blackboard;
AssetDatabase.SaveAssets();
既然有简单的方法 为什么还需要第二种方法?
下面举个例子:
采用第一种方法, 新增加个类MyBlackboard:
public class MyBlackboard: Blackboard { }
BehaviourTree类改为:
public class BehaviourTree: ScriptableObject{
[SerializeField]
public Blackboard board;
public void Init(){
this.board=new MyBlackboard();
}
}
这种情况下Create 出来的BehaviourTree asset获取到的board值只会是Blackboard类
强转的结果 (board as MyBlackboard) 只会是null
如果采用第二种方式 则是可以正确获取到想要的MyBlackboard
但需要将MyBlackboard 也就是子ScriptableObject对象的HideFlags属性 设置为HideFlags.HideInHierarchy