查看: 2679|回复: 3
打印 上一主题 下一主题

[教程] 在Unity3D中使用ScriptableObject进行序列化

[复制链接]

1557

主题

1

听众

1万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
454
精华
31

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2013-10-12 15:23:05 |只看该作者 |倒序浏览
ScriptableObject类型经常用于存储一些unity3d本身不可以打包的一些object,比如字符串,一些类对象等。用这个类型的子类型,则可以用BuildPipeline打包成assetbundle包供后续使用,非常方便。这样除了playerpref和c#文件读取外,另外的一种存取一些数据对象的方法
[csharp] view plaincopyprint?


  • using UnityEngine;   
  •   
  • public class XMLContains : ScriptableObject   
  •   
  • {   
  •   
  •     public string theXML;   
  •   
  • }   

By making your class enherit from ScriptableObject, it becomes an "Asset Type" to unity, in the sense that you can store them on disk, and use the Unity IDE interface to drag it from the assetsfolder to a behaviour or whatever. It also automatically plays nice with Unity's dependency tracking system that decides what does and what does not go into a webplayer. Going a bit further with this example, you could have let's say a TieFighter class, actually get some of its information (max health, max speed, acceleration), from your xml file, by making the TieFighter class look like this:

[csharp] view plaincopyprint?


  • using UnityEngine;   
  •   
  • public class TieFighter : MonoBehaviour   
  •   
  • {   
  •   
  •      public XMLContainer myXMLSettings;   
  •   
  •    
  •   
  •      void Awake()   
  •   
  •      {   
  •   
  •         //parse myXMLSettings.theXML into reasonable data   
  •   
  •      }   
  •   
  •    
  •   
  •      void Update()   
  •   
  •      {   
  •   
  •         //use the reasonable data   
  •   
  •      }   
  •   
  • }  

You could then attach the TieFighter script to a gameobject, and then drag your xml-asset from your assetsfolder onto the myXMLSettings public field.Please note that this example is much better at showing how you could use a ScriptableObject than how to properly implement a TieFighter, as I would never really have that parse an actual xml file on runtime. Tiefighters are too cool for xml anyway.
以上是不做成bundle包的形式,下面提供了一种打包成bundle资源,通过www来进行载入的方案:
通常,可以用BuildPipeline.BuildAssetBundle打包资源,这些资源包括模型、纹理、贴图等。其实也可以打包ScriptableObject,而ScriptableObject中可以存储任何数据类型。
以下为一个完整示例。
1、先创建一个类:
[csharp] view plaincopyprint?


  • using UnityEngine;   
  •   
  • using System.Collections.Generic;   
  •   
  • public class SysData : ScriptableObject   
  •   
  • {                 
  •   
  • public List<Vector3> content;   
  •   
  • }  

该类只有一个属性content。当然也可以声明更多属性、事件和方法。
在后面,这个类的实例将作为资源被打包。
2、创建一个编辑器脚本:
该脚本用于实例化SysData,设置一些数据,然后打包。
[csharp] view plaincopyprint?


  • using UnityEngine;   
  •   
  • using UnityEditor;   
  •   
  • using System.Collections.Generic;   
  •   
  • public class Export  
  •   
  • {         
  •   
  •   [MenuItem("Assets/Export")]           
  •   
  •   public static void Execute()   
  •   
  •   {               
  •   
  •    //实例化SysData               
  •   
  •    SysData sd = ScriptableObject.CreateInstance<SysData>();                             
  •   
  •     //随便设置一些数据给content                 
  •   
  •     sd.content = new List<Vector3>();                 
  •   
  •     sd.content.Add(new Vector3(1,2,3));                 
  •   
  •     sd.content.Add(new Vector3(4,5,6));                              
  •   
  •     // SysData将创建为一个对象,这时在project面板上会看到这个对象。                 
  •   
  •     string p = "Assets/SysData.asset";           
  •   
  •     AssetDatabase.CreateAsset(sd, p);                 
  •   
  •     Object o = AssetDatabase.LoadAssetAtPath(p, typeof(SysData));                              
  •   
  •     //打包为SysData.assetbundle文件。                 
  •   
  •     BuildPipeline.BuildAssetBundle(o, null, "SysData.assetbundle");                 
  •   
  •     //删除面板上的那个临时对象               
  •   
  •      AssetDatabase.DeleteAsset(p);                        
  •   
  •   }   
  •   
  • }   
  •   
  •    

3、运行时加载这个数据资源。
[csharp] view plaincopyprint?


  • IEnumerator Start ()   
  • {               
  • WWW www = new WWW("file://" + Application.dataPath + "/../SysData.assetbundle");               
  • yield return www;   
  •                
  • //转换资源为SysData,这个sd对象将拥有原来在编辑器中设置的数据。               
  • SysData sd = www.assetBundle.mainAsset as SysData;   
  • //如打印sd.content[0],将得到Vector3(1,2,3);               
  • print(sd.content[0]);  
  • }  

4、这其实是把整个对象实例打包,如果ScriptableObject属性中包括其他的类实例,则这些类需加上[Serializable]序列化。通过这种方法,可以将系统需要的数据(如角色分类、matrix4x4数据等等)打包,加载后直接转换为预定的类型,具有更高的效率。

分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

347

主题

1

听众

3111

积分

中级设计师

Rank: 5Rank: 5

纳金币
1147
精华
41

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2013-10-12 16:46:06 |只看该作者
顶一个!!
回复

使用道具 举报

nts    

3

主题

1

听众

743

积分

初级设计师

Rank: 3Rank: 3

纳金币
7
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2013-10-13 11:12:28 |只看该作者
谢谢学习了
回复

使用道具 举报

nts    

3

主题

1

听众

743

积分

初级设计师

Rank: 3Rank: 3

纳金币
7
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

地板
发表于 2013-10-13 11:15:35 |只看该作者
序列化应该是网络中才用的技术吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-29 06:26 , Processed in 0.087170 second(s), 32 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部