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

       

  • 相关阅读:
    Ajax调用asp.net后台代码
    浅谈Swift集合类型
    强大的swift字符串
    swift的运算符
    Swift的基本类型和流程控制
    Router和History (路由控制)-backbone
    jq里attr和prop的区别
    文本超出盒子的内容用省略号代替
    利用html5中的localStorage获取网页被访问的次数
    html5的本地存储localStorage和sessionStorage
  • 原文地址:https://www.cnblogs.com/alongu3d/p/3390259.html
Copyright © 2020-2023  润新知