Unity3D 学习笔记5 ——使用ScriptableObject进行序列化

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://linsh-tech.blog.csdn.net/article/details/50985756

<pre name="code" class="csharp">

        ScriptableObject:经常用于存储一些unity3d本身不能打包的对象(object),比如:字符串,一些类对象等。用这个类型的子类型,则可以用BuildPipeline打包成assetbundle包或者.assets文件供后续使用。

接下来我们通过一个简单的实例来展示如何使用ScriptableObject类:

步骤一:创建一个继承自ScriptableObject的类:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
/// <summary>
/// 保存表格导出的序列号数据
/// </summary>
public class GameDataScriptable : ScriptableObject {
    /// <summary>
    /// 技能字典
    /// </summary>
    public List<SkillItem> _SkillDictionary = new List<SkillItem>();
    public List<SkillItem> SkillDictionary {
        get { return _SkillDictionary; }
        set { _SkillDictionary = value; }
    }
}

        这里我们希望存在ScriptableObject中的是一个技能字典对象,SkillItem的数据结构可以自行定义,也可以用string或者int等简单数据类型来取代

using UnityEngine;
using System.Collections;
using System;
[System.Serializable]
/// <summary>
/// 表格数据结构
/// </summary>
public class SkillItem
{
    public int _SkillId;
    public string _SkillName;
    public int SkillId
    {
        get { return _SkillId; }
        set { _SkillId = value; }
    }
    public string SkillName
    {
        get { return _SkillName; }
        set { _SkillName = value; }
    }
}

步骤二:创建一个在Unity引擎中使用的编辑器脚本,并且此脚本必须存放在Assets目录下面的Editor文件夹下面,在这样的脚本都继承于Editor类:

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;

public class ToolsMenu:Editor{
    [MenuItem("打包工具/部分资源打包/打包表格数据")]
    public static void BuildConfigData()
    {
        Caching.CleanCache();
	//通过ScriptableObject创建一个对象的实例
	GameDataScriptable gs = ScriptableObject.CreateInstance<GameDataScriptable>();
	//对对象的属性进行赋值
	for(int i=1;i<3;i++){
		SkillItem item = new SkillItem();
		item.SkillId = i;			    
		item.SkillName = "技能" + i;  
		gs.SkillDictionary.Add(item);
	}
	//创建资源文件(可以在编辑器下直接编辑数据)
	AssetDatabase.CreateAsset(gs, "Assets/GameDataConfig.asset");
	//将资源反序列化为一个对象
	 Object o = AssetDatabase.LoadAssetAtPath("Assets/GameDataConfig.asset", typeof(GameDataScriptable));
         string targetPath = "Assets/GameData.assetbundle";
         //assetbundle文件只能在运行时加载,并且只能通过WWW加载
	 BuildPipeline.BuildAssetBundle(o, null, targetPath);
         //删除临时的资源文件
	 AssetDatabase.DeleteAsset("Assets/GameDataConfig.asset");
    }
}

步骤三:运行时加载这个数据资源

using UnityEngine;
using System.Collections;
public class LoadFileTest:MonoBehaviour
{
    IEnumerator Start ()
    {
      WWW www = new WWW("file://" + Application.dataPath + "/../GameDataConfig.assetbundle");
      yield return www;
      //转换资源为Test,这个test对象将拥有原来在编辑器中设置的数据。
      GameDataScriptable test = www.assetBundle.mainAsset as GameDataScriptable;
      Debug.Log("技能1的Id:"+test.SkillDictionary[0].SkillId);
    }
}


补充:这其实是把整个对象实例打包,如果ScriptableObject属性中包括其他的类实例,则这些类需加上[Serializable]序列化。通过这种方法,可以将系统需要的数据(如导表出来的数据等等)打包,加载后直接转换为预定的类型,可以大大加快数据加载读取的速度,具有更高的效率。

展开阅读全文

没有更多推荐了,返回首页