Unity3d Web3d资源的动态加载

                                    Unity3d Web3d资源的动态加载  

                                                                                                                                                                 @灰太龙

    参考了宣雨松的博客,原文出处http://www.xuanyusong.com/archives/2405,如果涉及到侵权,请通知我!

    Unity3d Web3d资源的动态加载中,用到了AssetBundle,在这儿我讲解一下,AssetBundle是个什么东西,AssetBundle可以将GameObject和这个GameObject所需要的资源一起打包进来,也就是说在Web端需要实例化这个资源的时候,就去下载这个所需要的资源,并且实例化这个东西!

  下面列出打包的代码:

  

 1 using UnityEngine;
 2 using System.Collections;
 3 using System.IO;
 4 using UnityEditor;
 5 public class ExportAssetBundle : EditorWindow {
 6 
 7     [MenuItem("Custom Editor/Create AssetBunldes Main")]
 8     static void CreateAssetBunldesMain ()
 9     {
10        //获取在Project视图中选择的所有游戏对象
11        Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);
12        //遍历所有的游戏对象
13        foreach (Object obj in SelectedAsset) 
14        {
15         string sourcePath = AssetDatabase.GetAssetPath (obj);
16         //本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,如果没有就创建一个,因为移动平台下只能读取这个路径
17         //StreamingAssets是只读路径,不能写入
18         //服务器下载:就不需要放在这里,服务器上客户端用www类进行下载。
19         string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + ".assetbundle";
20         if (BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)) {
21              Debug.Log(obj.name +"资源打包成功");
22         } 
23         else 
24         {
25             Debug.Log(obj.name +"资源打包失败");
26         }
27     }
28     //刷新编辑器
29     AssetDatabase.Refresh ();    
30 }
31     [MenuItem("Custom Editor/Create AssetBunldes ALL")]
32     static void CreateAssetBunldesALL ()
33     {
34 
35     Caching.CleanCache ();
36     string Path = Application.dataPath + "/StreamingAssets/ALL.assetbundle";
37 
38     Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);
39 
40     foreach (Object obj in SelectedAsset) 
41     {
42         Debug.Log ("Create AssetBunldes name :" + obj);
43     }
44 
45     //这里注意第二个参数就行
46     if (BuildPipeline.BuildAssetBundle (null, SelectedAsset, Path, BuildAssetBundleOptions.CollectDependencies)) {
47         AssetDatabase.Refresh ();
48     } else {
49 
50     }
51 }  
52     [MenuItem("Custom Editor/Foreach AssetBunldes ALL")]
53     static void ExportAllAssetBunldesAll()
54     {
55         StreamWriter write=new StreamWriter(Application.dataPath + "/StreamingAssets/gameobjects.txt");
56         Caching.CleanCache();
57         Object[] SeletedAsset=Selection.GetFiltered(typeof(Object),SelectionMode.DeepAssets);
58         foreach(Object obj in SeletedAsset)
59         {
60             write.Write(obj.name+" ");
61             Debug.Log(obj.name.ToString());
62             string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + ".assetbundle";
63             if (BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies))
64             {
65                 Debug.Log(obj.name +"资源打包成功");
66             } 
67             else 
68             {
69                Debug.Log(obj.name +"资源打包失败");
70             }
71         }
72         write.Flush();
73         write.Close();
74     }
75 }

      下面是要所有GameObject做成Prefab,然后对Prefab进行打包,打包成assetbundle文件,然后加载了这个assetbundle资源之后,就可以用Instantiate的方式,建立这个物体!

     选择Custom Editor/Foreach AssetBunldes ALL打包,可以打包所选择的所有预制件,并且生成了一个gameobjects.txt文件,打包的时候assetbundle的文件名和预制件的名字一样,

     那么我们初始化物体的时候,需要读取这个gameobjects.txt文件,依次初始化物体, 这样就实现了物体的分块加载!

  加载代码如下:

 

 1 using UnityEngine;
 2 using System.Collections;
 3 using System.Collections.Generic;
 4 using System.Net;
 5 public class Load : MonoBehaviour {
 6 
 7     // Use this for initialization
 8     void Start () {
 9         StartCoroutine(START());
10     }
11     private IEnumerator START()
12     {
13        string temp="";
14        string url="http://--------------------------------------------/gameobjects.txt";
15        WWW www=new WWW(url);
16        yield return www;
17        temp=www.text;
18        string asseturl="http://-----------------------------------";
19        string[] temp1=temp.Split(' ');
20        for(int i=0;i<temp1.Length;i++)
21        {
22             Debug.Log(temp1[i].ToString()+"-------------");
23             StartCoroutine(LoadMainCacheGameObject(asseturl+temp1[i]+".asset"));
24        }
25      }
26     private IEnumerator LoadMainCacheGameObject(string path)
27     {
28      WWW bundle = WWW.LoadFromCacheOrDownload(path,1);
29      yield return bundle;
30      //加载到游戏中
31      yield return Instantiate(bundle.assetBundle.mainAsset);
32      bundle.assetBundle.Unload(false);
33      }
34 }

          通过for循环依次加载物体!还有个问题就是打包的assetbundle中初始化出来的Prefab,有些脚本指向的GameObject或者Transform丢失,这个时候,可以有GameObject.FindWithTag的功能或者GameObject.Find来查找物体,也就是说专门有一个脚本去为另一个脚本赋值,这个脚本如果完成了赋值操作,就Destory(this)来销毁自己!举个例子!这个Set脚本,就是为加在同一个GameObject的物体的igui的一个脚本中变量赋值的,当赋值工作完成后,就Destory(this)来销毁脚本!

    

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class Set : MonoBehaviour {    
 5     
 6     iGUICode_demo demo;
 7     bool flag1=false;
 8     bool flag2=false;
 9     bool flag3=false;
10     bool flag4=false;
11     void Start()
12     {
13         demo=GetComponent<iGUICode_demo>();
14     }
15     // Update is called once per frame
16     void Update () {
17        if(!flag1)
18         {
19             GameObject temp1=GameObject.FindWithTag("AutoWander");
20             if(temp1!=null)
21             {
22                 demo._autoPerson=temp1;
23                 flag1=true;
24             }
25         }
26         if(!flag2)
27         {
28             GameObject temp2=GameObject.FindWithTag("ManualWander");
29             if(temp2!=null)
30             {
31                 demo._manualPerson=temp2;
32                 ObjManager._camera=temp2;
33                 flag2=true;
34             }
35         }
36         if(!flag3)
37         {
38             GameObject temp3= GameObject.Find("iGUIListBoxSimple(Clone)");
39             if(temp3!=null)
40             {
41                 ObjManager._window=temp3;
42                 flag3=true;
43             }
44         }
45         if(flag1&&flag2&&flag3)
46         {
47             demo._autoPerson.SetActive(false);
48             Destroy(this);
49         }
50     }
51 }

 

 

 

     1.我看到别人把每个物体导出为.unity3d,然后也导出了变换信息,我认为这是不需要的,因为预制件中已经包含了这些信息!

     2.还有就是有的问题需要注意,比如角色站在地板上,那么如果角色在地板之前加载,那么角色会掉下去,这个时候,要先加载地板,或者后加载地板,设置人物不受重力影响!等地板加载完之后,再设置人物受重力影响,防止掉落下去!

   

posted @ 2013-10-27 00:10  广州阿龙  阅读(764)  评论(1编辑  收藏  举报