查看: 4012|回复: 0
打印 上一主题 下一主题

unity3d动态加载及生成配置文件(二)

[复制链接]

1602

主题

1

听众

2万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
24658
精华
6

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

跳转到指定楼层
楼主
发表于 2012-5-10 15:12:37 |只看该作者 |倒序浏览
这里面用到了C#的事件机制,大家可以看看我以前翻译过的国外一个牛人的文章。C# 事件和unity3d

在 start方法里调用ResourceManager,先加载配置文件。每一次调用update方法,MainMonoBehavior会把update 事件分发给ResourceManager,因为ResourceManager注册了MainMonoBehavior的update事件。
辅助类:ResourceManager.cs

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

using LitJson;

using System.Net;

public class ResourceManager

{
// Use this for initialization

        private MainMonoBehavior mainMonoBehavior;

        private   string mResourcePath;

        private Scene mScene;

        private Asset mSceneAsset;

        private static ResourceManager resourceManager=new ResourceManager();//如果没有new 会出现没有实例化的错误

        private Dictionary<string ,WWW > wwwCacheMap=new Dictionary<string,WWW>();//这个新添加的原文代码中没有定义它 应该是个字典

       public static  ResourceManager getInstance( )

        {

                return resourceManager;//静态函数中不能使用非静态成员

        }

        public  ResourceManager()

        {

                mainMonoBehavior = GameObject.Find("Main Camera").GetComponent<MainMonoBehavior>();

                mResourcePath ="file://"+Application.dataPath+"/..";

        }

      

        public void LoadSence(string fileName)

        {

                //Debug.Log(fileName);

                mSceneAsset = new Asset();

                mSceneAsset.Type = Asset.TYPE_JSON;//后面类型判断有用

                mSceneAsset.Source = fileName;

                mainMonoBehavior.UpdateEvent += OnUpdate;//添加监听函数

        }
public void OnUpdate(GameObject dispatcher)//该函数是监听函数,每帧都会被调用(它的添加是在MainMonoBehavior的start函数中通过调用本地LoadSence函数)

        {

                if (mSceneAsset != null)//表示已经通过了new操作分配类内存空间但是资源还没有加载完

                {

                        LoadAsset(mSceneAsset);//这个函数里面会通过判断,使www的new操作只执行一次

                        if (!mSceneAsset.isLoadFinished)//C#中 bool类型默认是false

                        {

                               return;

                        }

                        mScene = null;

                        mSceneAsset = null;

                }

                mainMonoBehavior.UpdateEvent -= OnUpdate;//当所有资源被加载后,删除监听函数。

        }

        //最核心的函数

     private Asset LoadAsset(Asset asset)

        {

                string fullFileName =mResourcePath+"/"+ asset.Source;// mResourcePath + "/" + asset.Source;

                Debug.Log("fullFileName=" + fullFileName);

                //if www resource is new, set into www cache

                if (!wwwCacheMap.ContainsKey(fullFileName))

                {//自定义字典 查看开头的定义

                        if (asset.www == null)

                        {//表示www还没有new操作

                                asset.www = new WWW(fullFileName);

                                return null;

                        }

                        if (!asset.www.isDone)

                        {

                                return null;

                        }

                        wwwCacheMap.Add(fullFileName, asset.www); //该字典是作为缓存的作用,如果之前已经加载过同样的Unity3D格式文件,那么不需要在加载,直接拿来用就行了。  

                }  

                if (asset.Type == Asset.TYPE_JSON)

                { //Json 表示当txt文件被首次加载时的处理

                        if (mScene == null)

                        {        

                            string jsonTxt = mSceneAsset.www.text;

                            Debug.Log("jsonTxt=" + jsonTxt);

                            mScene = JsonMapper.ToObject<Scene>(jsonTxt);//mScene是个Asset对象列表,也就是Json文件需要一个AssetList列表对象,注意名字的统一,列表中Asset对象中的成员名称要和txt                //文件中的相关名称统一 不然JsonMapper无法找到

                         }

                        //load scene

                        foreach (Asset sceneAsset in mScene.AssetList)

                        {

                                if (sceneAsset.isLoadFinished)

                                {

                                        continue;

                                }

                                else

                                {

                                        LoadAsset(sceneAsset);//这里的处理就是 下面 Asset.TYPE_GAMEOBJECT的处理方式,注意是递归函数的调用

                                        if (!sceneAsset.isLoadFinished)

                                        {

                                            return null;

                                         }

                                 }

                        }

                }

                else if (asset.Type == Asset.TYPE_GAMEOBJECT)//处理文件中具体信息,嵌套关系或者直接是一个GameObject对象,与上面的代码有联系,Asset创建时候的构造函数中设置成

                //TYPE_GAMEOBJECT类型

                { //Gameobject

                        if (asset.gameObject == null)//如果不为null 表示已经通过wwwCacheMap加载了资源包中所包含的资源(fullFileName仅仅是一个文件,资源包中资源是分散的GameObject对象),不需要在重新加载

                        {

                                wwwCacheMap[fullFileName].assetBundle.LoadAll();//已经通过new WWW操作完成了加载,该函数用来加载包含着资源包中的资源

                                GameObject go = (GameObject)GameObject.Instantiate(wwwCacheMap[fullFileName].assetBundle.mainAsset);

                                UpdateGameObject(go, asset);

                                asset.gameObject = go;

                        }

                        if (asset.AssetList != null)//有嵌套关系

                        {

                                foreach (Asset assetChild in asset.AssetList)

                                {

                                        if (assetChild.isLoadFinished)

                                        {

                                                continue;

                                        }

                                        else

                                        {

                                                Asset assetRet = LoadAsset(assetChild);

                                                if (assetRet != null)//这个if else 语句是为了防止你的配置文件中的GameObject对象路径不正确,导致访问空指针。

{

                                                        assetRet.gameObject.transform.parent = asset.gameObject.transform;

                                                }

                                                else

                                                {

                                                        return null;

                                                }

                                        }

                                }

                        }

                }

                asset.isLoadFinished = ***e;

                return asset;

        }

        private void UpdateGameObject(GameObject go, Asset asset)

        {

                //name

                go.name = asset.Name;

                //position

                Vector3 vector3 = new Vector3((float)asset.Position[0], (float)asset.Position[1], (float)asset.Position[2]);

                go.transform.position = vector3;

                //rotation

               vector3 = new Vector3((float)asset.Rotation[0], (float)asset.Rotation[1], (float)asset.Rotation[2]);

                go.transform.eulerAngles = vector3;

        }

}
Asset.cs类:

using UnityEngine;

using System.Collections.Generic;

public class Asset

{

        public const byte TYPE_JSON = 1;

        public const byte TYPE_GAMEOBJECT = 2;

        public Asset()

        {

            //default type is gameobject for json load

            Type = TYPE_GAMEOBJECT;

        }

        public byte Type

        {

            get;

            set;

        }

        public string Name

        {

            get;

            set;

        }

        public string Source

        {

            get;

            set;

        }

        public double[] Bounds

        {

            get;

            set;

        }

      

        public double[] Position

        {

            get;

            set;

        }

        public double[] Rotation

        {

            get;

            set;

        }

        public List<Asset> AssetList

        {

            get;

            set;

        }

        public bool isLoadFinished

        {

            get;

            set;

        }

        public WWW www

        {

            get;

            set;

        }

        public GameObject gameObject

        {

            get;

            set;

        }

}

Scene.cs类:

using System.Collections.Generic;
public class Scene

{

        public List<Asset> AssetList

        {

            get;

            set;

        }

}
生成.unity3d代码:

using UnityEngine;

using UnityEditor;

using System.IO;

using System;

using System.Text;

using System.Collections.Generic;

using LitJson;

public class BuildAssetBundlesFromDirectory

{

      static List<JsonResource> config=new List<JsonResource>();

      static Dictionary<string, List<JsonResource>> assetList=new Dictionary<string, List<JsonResource>>();

        [@MenuItem("Asset/Build AssetBundles From Directory of Files")]//这里不知道为什么用"@",添加菜单

        static void ExportAssetBundles ()

        {//该函数表示通过上面的点击响应的函数

                   assetList.Clear();

                   string path = AssetDatabase.GetAssetPath(Selection.activeObject);//Selection表示你鼠标选择激活的对象

                  Debug.Log("Selected Folder: " + path);

      

      

                  if (path.Length != 0)

                  {

                           path = path.Replace("Assets/", "");//因为AssetDatabase.GetAssetPath得到的是型如Assets/文件夹名称,且看下面一句,所以才有这一句。

                            Debug.Log("Selected Folder: " + path);

                           string [] fileEntries = Directory.GetFiles(Application.dataPath+"/"+path);//因为Application.dataPath得到的是型如 "工程名称/Assets"

                           

                           string[] div_line = new string[] { "Assets/" };

                           foreach(string fileName in fileEntries)

                           {

                                    j++;

                                    Debug.Log("fileName="+fileName);

                                    string[] sTemp = fileName.Split(div_line, StringSplitOptions.RemoveEmptyEntries);

                                    string filePath = sTemp[1];

                                     Debug.Log(filePath);

                                    filePath = "Assets/" + filePath;

                                    Debug.Log(filePath);

                                    string localPath = filePath;

                                    UnityEngine.Object t = AssetDatabase.LoadMainAssetAtPath(localPath);

                                   

                                     //Debug.Log(t.name);

                                    if (t != null)

                                    {

                                            Debug.Log(t.name);

                                            JsonResource jr=new JsonResource();

                                            jr.Name=t.name;

                                            jr.Source=path+"/"+t.name+".unity3d";

                                              Debug.Log( t.name);

                                            config.Add(jr);//实例化json对象

                                              string bundlePath = Application.dataPath+"/../"+path;

                                               if(!File.Exists(bundlePath))

                                                {

                                                   Directory.CreateDirectory(bundlePath);//在Asset同级目录下相应文件夹

                                                }

                                              bundlePath+="/"  + t.name + ".unity3d";

                                             Debug.Log("Building bundle at: " + bundlePath);

                                             BuildPipeline.BuildAssetBundle(t, null, bundlePath, BuildAssetBundleOptions.CompleteAssets);//在对应的文件夹下生成.unity3d文件

                                    }

                           }

                            assetList.Add("AssetList",config);

                            for(int i=0;i<config.Count;i++)

                            {

                                    Debug.Log(config.Source);

                            }

                  }

                string data=JsonMapper.ToJson(assetList);//序列化数据

                Debug.Log(data);

        string jsonInfoFold=Application.dataPath+"/../Scenes";

        if(!Directory.Exists(jsonInfoFold))

        {

            Directory.CreateDirectory(jsonInfoFold);//创建Scenes文件夹

        }

                string fileName1=jsonInfoFold+"/json.txt";

                if(File.Exists(fileName1))

                {

                    Debug.Log(fileName1 +"already exists");

                    return;

                }

                UnicodeEncoding uni=new UnicodeEncoding();

                  

                using(  FileStream  fs=File.Create(fileName1))//向创建的文件写入数据

                {

                        fs.Write(uni.GetBytes(data),0,uni.GetByteCount(data));

                        fs.Close();

                }

      }

}



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

使用道具 举报

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

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

GMT+8, 2024-11-29 01:46 , Processed in 0.103605 second(s), 28 queries .

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

© 2008-2019 Narkii Inc.

回顶部