码迷,mamicode.com
首页 > 编程语言 > 详细

Unity5.x版本AssetBundle加载研究

时间:2015-10-18 16:41:10      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:

之前说了 “Unity5.x版本AssetBundle打包研究”,没看过的请先看一下:http://www.shihuanjue.com/?p=57
再来看本文,有一定的连接性。

先梳理一下思路:
要加载一个资源A,必须先去加载它的所有依赖资源
要知道这个资源A依赖了哪些资源,必须先去加载AssetBundleManifest
通过AssetBundleManifest对象的GetAllDependencies(A)方法,获取它依赖的所有资源。
依赖资源都加载了,就可以去真正加载资源A了。

注意点:
1.资源A加载完了后,要记得Unload(false),资源A的依赖资源要在 资源A加载完成后,才能Unload(false),否则无法正常加载资源A
2.不Unload的话也可以,那就自己做一个字典记录所有加载过的AssetBundle,还有它们的引用计数器。那样就可以先判断是否存在,然后再确定是否要去加载。

我下面的例子,采用1的方式。就是加载完了后就Unload的方式。
上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
 
public class AssetBundleLoaderMgr : Singleton<AssetBundleLoaderMgr>
{
    public string m_assetPath = Application.streamingAssetsPath;
    string assetTail = ".unity3d";
 
    #region LoadAssetBundle
 
    /// <summary>
    /// 加载目标资源
    /// </summary>
    /// <param name="name"></param>
    /// <param name="callback"></param>
    public void LoadAssetBundle(string name, Action<UnityEngine.Object> callback)
    {
        name = name + assetTail;//eg:ui/panel.unity3d
 
        Action<List<AssetBundle>> action = (depenceAssetBundles) =>
        {
 
            string realName = this.GetRuntimePlatform() + "/" + name;//eg:Windows/ui/panel.unity3d
 
            LoadResReturnWWW(realName, (www) =>
            {
                int index = realName.LastIndexOf("/");
                string assetName = realName.Substring(index + 1);
                assetName = assetName.Replace(assetTail, "");
                AssetBundle assetBundle = www.assetBundle;
                UnityEngine.Object obj = assetBundle.LoadAsset(assetName);//LoadAsset(name),这个name没有后缀,eg:panel
 
                //卸载资源内存
                assetBundle.Unload(false);
                for (int i = 0; i < depenceAssetBundles.Count; i++)
                {
                    depenceAssetBundles[i].Unload(false);
                }
 
                //加载目标资源完成的回调
                callback(obj);
            });
 
        };
 
        LoadDependenceAssets(name, action);
    }
 
    /// <summary>
    /// 加载目标资源的依赖资源
    /// </summary>
    /// <param name="targetAssetName"></param>
    /// <param name="action"></param>
    private void LoadDependenceAssets(string targetAssetName, Action<List<AssetBundle>> action)
    {
        Debug.Log("要加载的目标资源:" + targetAssetName);//ui/panel.unity3d
        Action<AssetBundleManifest> dependenceAction = (manifest) =>
        {
            List<AssetBundle> depenceAssetBundles = new List<AssetBundle>();//用来存放加载出来的依赖资源的AssetBundle
 
            string[] dependences = manifest.GetAllDependencies(targetAssetName);
            Debug.Log("依赖文件个数:" + dependences.Length);
            int length = dependences.Length;
            int finishedCount = 0;
            if (length == 0)
            {
                //没有依赖
                action(depenceAssetBundles);
            }
            else
            {
                //有依赖,加载所有依赖资源
                for (int i = 0; i < length; i++)
                {
                    string dependenceAssetName = dependences[i];
                    dependenceAssetName = GetRuntimePlatform() + "/" + dependenceAssetName;//eg:Windows/altas/heroiconatlas.unity3d
 
                    //加载,加到assetpool
                    LoadResReturnWWW(dependenceAssetName, (www) =>
                    {
                        int index = dependenceAssetName.LastIndexOf("/");
                        string assetName = dependenceAssetName.Substring(index + 1);
                        assetName = assetName.Replace(assetTail, "");
                        AssetBundle assetBundle = www.assetBundle;
                        UnityEngine.Object obj = assetBundle.LoadAsset(assetName);
                        //assetBundle.Unload(false);
                        depenceAssetBundles.Add(assetBundle);
 
                        finishedCount++;
 
                        if (finishedCount == length)
                        {
                            //依赖都加载完了
                            action(depenceAssetBundles);
                        }
                    });
                }
            }
        };
        LoadAssetBundleManifest(dependenceAction);
    }
 
    /// <summary>
    /// 加载AssetBundleManifest
    /// </summary>
    /// <param name="action"></param>
    private void LoadAssetBundleManifest(Action<AssetBundleManifest> action)
    {
        string manifestName = this.GetRuntimePlatform();
        manifestName = manifestName + "/" + manifestName;//eg:Windows/Windows
        LoadResReturnWWW(manifestName, (www) =>
        {
            AssetBundle assetBundle = www.assetBundle;
            UnityEngine.Object obj = assetBundle.LoadAsset("AssetBundleManifest");
            assetBundle.Unload(false);
            AssetBundleManifest manif = obj as AssetBundleManifest;
            action(manif);
        });
    }
    #endregion
 
    #region ExcuteLoader
    public void LoadResReturnWWW(string name, Action<WWW> callback)
    {
        string path = "file://" + this.m_assetPath + "/" + name;
        Debug.Log("加载:" + path);
        StartCoroutine(LoaderRes(path, callback));
    }
 
    IEnumerator LoaderRes(string path, Action<WWW> callback)
    {
        WWW www = new WWW(path);
        yield return www;
        if (www.isDone)
        {
            callback(www);
        }
    }
    #endregion
 
    #region Util
    /// <summary>
    /// 平台对应文件夹
    /// </summary>
    /// <returns></returns>
    private string GetRuntimePlatform()
    {
        string platform = "";
        if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor)
        {
            platform = "Windows";
        }
        else if (Application.platform == RuntimePlatform.Android)
        {
            platform = "Android";
        }
        else if (Application.platform == RuntimePlatform.IPhonePlayer)
        {
            platform = "IOS";
        }
        else if (Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXEditor)
        {
            platform = "OSX";
        }
        return platform;
    }
}
#endregion

测试一下咯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class TestAssetBundleLoader : MonoBehaviour
{
    Dictionary<string, GameObject> GameObjectPool = new Dictionary<string, GameObject>();
 
    void Start()
    {
        //要加载的资源的队列
        Queue<string> needLoadQueue = new Queue<string>();
        needLoadQueue.Enqueue("ui/plane");
        needLoadQueue.Enqueue("ui/cube");
        needLoadQueue.Enqueue("ui/sphere");
 
        Load(needLoadQueue);
    }
 
    void Load(Queue<string> needLoadQueue)
    {
        if (needLoadQueue.Count > 0)
        {
            string needLoadAssetName = needLoadQueue.Dequeue();
            AssetBundleLoaderMgr.Instance.LoadAssetBundle(needLoadAssetName, (obj) =>
            {
                GameObject go = GameObject.Instantiate(obj) as GameObject;
                int index = needLoadAssetName.LastIndexOf("/");
                string assetName = needLoadAssetName.Substring(index + 1);
 
                //加载出来的GameObject放到GameObjectPool存储
                GameObjectPool.Add(assetName, go);
 
                Load(needLoadQueue);
            });
        }
        else
        {
            Debug.Log("all finished");
        }
    }
}

有图有真相
技术分享
技术分享

可能代码写的还有很多优化的地方 ,毕竟100个人有100种写法,思路才是最重要的。你说呢?
其实我想说的是,代码都在了,自己尝试一下吧!

Unity5.x版本AssetBundle加载研究

标签:

原文地址:http://www.cnblogs.com/joeshifu/p/4889579.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!