原文:http://blog.csdn.net/xv_ly15/article/details/9330617
简介
开发人员一般通过BuildPipeline函数去打包文件,然后通过WWW去下载
但是BuildPipeline打包的对象类型是有限制的,像GameObject,TextAsset这些文件是可以直接打包的,但是,如果要读取一些Unity不支持的类型,我们就需要用到ScriptableObject了。这里用打包Csv表作为例子示例一下
实现
1. 编辑ScriptObject对象
首先,csv表的内容就是一段字符串,又或者说是一段bytes,看程序需求,我这里把csv表的内容当成一段bytes读取,吧
所以,csv表的ScriptableObject可以这样写
- using UnityEngine;
- using System.Collections;
- public class soCsv : ScriptableObject
- {
- public string fileName;
- public byte[] content;
- }
2. 打包文件
有了Csv的ScriptableObject后,就可以开始写打包函数了
简单说一下流程:
1.获取选中的csv表对象
2.赋值到刚声明的csv表对应的ScriptableObject
3.用该ScriptableObject生成Asset
4.读取生成的Asset后打包(生成与读取asset的过程有点别扭,但只有这样获得的Object对象,才能打包成功...)
- using UnityEngine;
- using System.Collections;
- using UnityEditor;
- using System.IO;
- using System.Collections.Generic;
- public class BuildTest : MonoBehaviour
- {
- [MenuItem("Assets/Build Csv")]
- static void BuildCsv()
- {
- string applicationPath = Application.dataPath;
- string saveDir = applicationPath + "/Resources_out/";
- string savaPath = saveDir + "csv.unity3d";
- //获取选中的对象
- /*关于SelectionMode参数,目前我只用过Assets,DeepAssets,其他的暂且不说
- Assets:获取当前选中的单一对象
- DeepAssets:获取当前选中的对象,如果选中的文件夹,则会获取到文件夹的子对象
- *
- *
- Unfiltered : Return the whole selection.
- TopLevel : Only return the topmost selected transform. A selected child of another selected transform will be filtered out.
- Deep: Return the selection and all child transforms of the selection.
- ExcludePrefab : Excludes any prefabs from the selection.
- Editable :Excludes any objects which shall not be modified.
- Assets :Only return objects that are assets in the Asset directory.
- DeepAssets : If the selection contains folders, also include all assets and subfolders within that folder in the file hierarchy.
- *
- */
- Object[] selections = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
- List<Object> outs = new List<Object>();
- for (int i=0,max=selections.Length; i<max; i++)
- {
- Object obj = selections[i];
- //asset path : 相对Asset目录
- string fileAssetPath = AssetDatabase.GetAssetPath(obj);
- //判断后缀
- if (fileAssetPath.Substring(fileAssetPath.LastIndexOf('.') + 1) != "csv")
- continue;
- //
- string fileWholePath = applicationPath + "/" + fileAssetPath.Substring(fileAssetPath.IndexOf("/"));
- //
- soCsv csv = ScriptableObject.CreateInstance<soCsv>();
- csv.fileName = obj.name;
- csv.content = File.ReadAllBytes(fileWholePath);
- //这一个存与读的步骤是否必要的?
- string assetPathTemp = "Assets/Resources_Local/Temp/" + obj.name + ".asset";
- AssetDatabase.CreateAsset(csv, assetPathTemp);
- Object outObj = AssetDatabase.LoadAssetAtPath(assetPathTemp, typeof(soCsv));
- //
- Debug.Log("package : " + outObj.name);
- outs.Add(outObj);
- }
- //
- Object[] outObjs = outs.ToArray();
- if (BuildPipeline.BuildAssetBundle(null, outs.ToArray(), savaPath))
- Debug.Log("build " + savaPath + " success,length = " + outObjs.Length);
- else
- Debug.LogWarning("build " + savaPath + " failed");
- }
- }
3. 下载并解析内容
- using UnityEngine;
- using System.Collections;
- using System.IO;
- using LumenWorks.Framework.IO.Csv;
- public class Test : MonoBehaviour {
- WWW w;
- string path ;
- void Start () {
- //File协议主要用于访问本地计算机中的文件,所以这里还需要加file:///
- path = "file:///" + Application.dataPath + "/Resources_out/csv.unity3d";
- w = new WWW(path);
- }
- // Update is called once per frame
- void Update () {
- if (w != null)
- {
- if (w.isDone)
- {
- Debug.Log("download " + path);
- Debug.Log(w.assetBundle.mainAsset);
- /*loadall的参数如果不指定类型,很可能会读取到额外的内容
- * 像我测试的时候,就发现一直多出了一个名字叫soCsv的对象
- * 最好还是指定一下类型
- * */
- Object[] objs = w.assetBundle.LoadAll(typeof(soCsv));
- Debug.Log("count : " + objs.Length);
- for (int i = 0, max = objs.Length; i < max; i++)
- {
- Object obj = objs[i];
- soCsv csv= obj as soCsv;
- //用string表做一个例子吧
- if (csv.fileName != "string")
- {
- continue;
- }
- //
- MemoryStream ms = new MemoryStream(csv.content);
- if (ms == null)
- {
- Debug.LogWarning("转换csv失败");
- continue;
- }
- StreamReader sr = new StreamReader(ms);
- TextReader tr = sr as TextReader;
- if (tr == null)
- {
- Debug.LogWarning("text reader is null");
- continue;
- }
- CsvReader cr = new CsvReader(tr, true);
- if (cr == null)
- {
- Debug.LogWarning("CsvReader is null");
- continue;
- }
- //将字段头输出
- string[] headers = cr.GetFieldHeaders();
- foreach (string szHeader in headers)
- Debug.Log(szHeader);
- }
- w = null;
- }
- }
- }
- }