Unity3d ScriptableObject那些事

 

最近在写行为树编辑器 数据存储用到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

 

 

 

你可能感兴趣的:(Unity3d)