AssetBundles 是Unity使用的一种资源格式,AssetBundles资源可以在不同项目交叉单独使用,Unity中主要用AssetBundles使资源和可执行文件分离。
0x01:生成AssetBundles
AssetBundle可以调用Unity接口:
1 |
<code class="hljs avrasm">BuildPipeLine.BuildAssetBundle(Object mainAsset, Object[] assets, string pathName, BuildAssetBundleOptions assetBundleOptions = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BuildTarget targetPlatform = BuildTarget.WebPlayer)</code> |
0x02:加载AssetBundles
1、AssetBundles存储路径:
Streaming Assets
通过路径访名可以访问,游戏中如果有视频文件,必须放在这个路径。根目录通过Application.streamingAssetsPath 来访问
不同平台对应的路径
1 2 3 |
<code class="hljs cs"> path = "file://" + Application.dataPath + "/StreamingAssets"; //pc path = "file://" + Application.dataPath + "/Raw"; // ios path = "jar:file://" + Application.dataPath + "!/assets/"; // android</code> |
PersistentDataPath
此路径可以保存数据,每次安装应用不会覆盖此目录
加载AssetBundle通过
1 |
<code class="hljs ini">path = "file://" + Application.persistentDataPath;</code> |
Temporary CachePath
此路径保存零时文件,可能会被OS清除
加载AssetBundle通过
1 |
<code class="hljs ini">path = "file://" + Application.temporaryCachePath;</code> |
2、AssetBundles加载方式
1 2 3 4 5 6 7 8 9 10 11 12 |
<code class="hljs cs">IEnumerator LoadAssetBundle(string fileUrl, LoadCallback callBack) { WWW www = new WWW(fileUrl); yield return www; if(www.error != null) { callBack(www.assetBundle); }
www.Dispose(); www = null; }</code> |
0x03:自动化生成AssetBundle
对于生成个别资源手动写代码很容易,但对于大中型项目,AssetBundle需要随时生成任何一个目录 ,这时需要完整的自动化生成流程。
1、switch 平台
2、加载生成AssetBundle 目录配置文件
3、生成AssetBundle
如果AssetBundle只用于打包补丁,指定Resources目录的文件生成相应的AssetBundle即可,当游戏启动的时候,资源会下载在可写目录。这时可以通过下面的方式来判断是否加载新的资源:
1 2 3 4 5 6 7 8 9 10 |
<code class="hljs cs">public bool IsNewAssetExist(string filePath) { string fileFullPath = Path.Combine(Application.dataPath, filePath); if (File.Exists(fileFullPath)) { return true; }
return false; }</code> |
更多应给是将这些可变的资源放置到Assets目录的其他文件夹,然后生成AssetBundle到StreamingAssets文件下,这样的好处一个是Resources文件下文件少,容易整理,因为Unity会把Resources低下所有文件打包到App里,所以这样的资源管理方式也有助于Unity底下的资源整理。同时将这部分资源打包分离到外部,不打入app里,而是通过下载到本地可写目录,结果就是可以让安装包很小,对于Google Play 这绝对是最好的消息。如果资源一开始打包到StreamingAssets里,通过如下方式加载:
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 |
<code class="hljs cs">private string StreamingPath { get { if (Application.platform == RuntimePlatform.Android) { return "jar:file://" + Application.dataPath + "!/assets/"; } else if (Application.platform == RuntimePlatform.IPhonePlayer) { return "file://" + Application.dataPath + "/Raw/"; } else { return "file://" + Application.dataPath + "/StreamingAssets/"; } } }
public string GetAssetPath(string filePath) { string fileFullPath = Path.Combine(Application.dataPath, filePath); if (File.Exists(fileFullPath)) { return "file://" + fileFullPath; } return StreamingPath + filePath; }</code> |
0x04:AssetBundle 的优缺点
优点
1、减小安装包大小
2、异步加载
3、更新资源
缺点
1、逻辑复杂度
2、增加下载功能
3、资源加载逻辑
4、资源卸载逻辑
5、加载时序问题解决
6、添加生成AssetBundle逻辑
注意
1、下载的AssetBundle需要设置Iphone.SetNoBackupFlag()
2、不同平台下的AssetBundle不能通用
3、如果资源不放在Resources,那Unity Editor模式下如何加载资源,可以使用:
1 |
<code class="hljs delphi">public static Object LoadAssetAtPath(string assetPath, Type type);</code> |
0x05:总结
目前市场上很多游戏都需要支持打补丁包,对于资源补丁包,Unity提供的方式就是AssetBundle,这篇文章里对于很多涉及到细节并不是面面俱到,比如资源都是通过携程加载,如果正在加载中,再重复加载同样的资源会如何?如何加载一个资源列表?这些东西只有在具体项目中,才会有深入的体会。
同时在做Unity项目中,最好做到对Unity的帮助文档非常熟悉,并且动手将Unity提供的接口进行了实验,这样在做Unity项目的时候才能做到好的抉择,无论是性能效率方面,还是资源管理方面,就可以做到游刃有余。