找回密码
 立即注册
查看: 443|回复: 0

Unity教程之-Unity5.x版本AssetBundle加载研究

[复制链接]
发表于 2021-12-21 19:29 | 显示全部楼层 |阅读模式
之前说了 “unity4.x版本AssetBundle打包研究”,没看过的请先看一下《Unity教程之-Unity3d打包Assetbundle并加载》,再来看本文,有一定的连接性。
先梳理一下思路:
要加载一个资源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      
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public classAssetBundleLoaderMgr : Singleton<AssetBundleLoaderMgr>
{
public string m_assetPath = Application.streamingAssetsPath;
string assetTail = ".unity3d";

#region LoadAssetBundle

/// <summary>
/// 加载目标资源
/// </summary>
/// <param name="name"></param>
/// <param name="callback"></param>
publicvoidLoadAssetBundle(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 (inti = 0; i < depenceAssetBundles.Count; i++)
{
depenceAssetBundles.Unload(false);
}

//加载目标资源完成的回调
callback(obj);
});

};

LoadDependenceAssets(name, action);
}

/// <summary>
/// 加载目标资源的依赖资源
/// </summary>
/// <param name="targetAssetName"></param>
/// <param name="action"></param>
privatevoidLoadDependenceAssets(string targetAssetName, Action<List<AssetBundle>> action)
{
Debug.Log("要加载的目标资源:"+ targetAssetName);//ui/panel.unity3d
Action<AssetBundleManifest> dependenceAction = (manifest) =>
{
List<AssetBundle> depenceAssetBundles = newList<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 (inti = 0; i < length; i++)
{
string dependenceAssetName = dependences;
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>
privatevoidLoadAssetBundleManifest(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
publicvoidLoadResReturnWWW(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 = newWWW(path);
yield returnwww;
if (www.isDone)
{
callback(www);
}
}
#endregion

#region Util
/// <summary>
/// 平台对应文件夹
/// </summary>
/// <returns></returns>
privatestring GetRuntimePlatform()
{
string platform = "";
if (Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor)
{
platform = "Windows";
}
elseif(Application.platform == RuntimePlatform.Android)
{
platform = "Android";
}
elseif(Application.platform == RuntimePlatform.IPhonePlayer)
{
platform = "IOS";
}
elseif(Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXEditor)
{
platform = "OSX";
}
returnplatform;
}
}



测试一下咯
?
       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 classTestAssetBundleLoader : MonoBehaviour
{
Dictionary<string, GameObject> GameObjectPool = newDictionary<string, GameObject>();

void Start()
{
//要加载的资源的队列
Queue<string> needLoadQueue = newQueue<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种写法,思路才是最重要的。你说呢?
其实我想说的是,代码都在了,自己尝试一下吧!好了,本篇unity3d教程到此结束,下篇我们再会!
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2025-5-14 22:23 , Processed in 0.132687 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表