前言
正在完善,比较乱
资源种类
1.在Editor的Resources目录下的资源
2.放在StreamingAsset打包出来的AssetBundle
AssetBundle概念
1,AssetBundle是一个压缩包包含模型、贴图、预制体、声音、甚至整个场景,可以在游戏运行的时候被加载;
2,AssetBundle自身保存着互相的依赖关系;
3,压缩包可以使用LZMA和LZ4压缩算法,减少包大小,更快的进行网络传输;
4,把一些可以下载内容放在AssetBundle里面,可以减少安装包的大小;
AB打包策略
1.如果资源需要热更 不放Resource,使用固定的某个或者几个文件夹放,打包的时候,把这些文件夹打入
2.根据游戏特性来决定打包的粒度,对于自由的游戏,可能每个资源都需要打作一个AB,对于比较固定的玩法,可以某一个玩法或者章节资源,打作一个大的AB,这样对于加载的消耗和压力,都会比较好。
AB打包流程
1.设计AssetBundle包
设计就是加载策略,战略打包文件夹或文件,例如那些文件或文件夹,打包后到了哪个文件夹内,这是AB的路径
打包战略由游戏决定 如果游戏很自由 可能一个包就是一个Prefab 如果游戏出现的内容固定 可以把固定的内容都打成一个包
AB包可能是很大的 好几个文件夹好几个Prefab打成一个AB包 也可能1个Prefab就是一个AB包
如果在UnityProject内选择一个文件或文件夹可以发现右下角窗口 可以设计前缀和后缀 加载这就是AssetBundle的名字
先LoadAssetBundle 然后再LoadAsset 而里面的asset才是自己真正需要的Prefab之类的东西
shader问题https://docs.unity3d.com/Manual/class-GraphicsSettings.html
2.打AB包成Asset
给Prefab改名字
打包使用接口BuildPipeline.BuildAssetBundles(
参数1路径 用 Application.dataPath + "/StreamingAssets"
参数2 不知道 参数3 打包的平台
3.加载依赖
例如一个预制体prefab可能会依赖模型、贴图、材质。
4.预加载
yield return 下列情况
Resources.LoadAsync
AssetBundle.LoadFromFileAsync
然后cache起来
因为他们都继承了AsyncOperation 然后又继承自YeildInstruction 所以可以协程等待
5.加载
如果有cache 直接加载
如果是loding 转同步加载
如果什么都没 直接同步加载
unty有很多加载方式,基本为Resource文件夹的内资源的加载,Editor加载AssetDatabase.Load和打包加载异步加载AssetBundle.Load
加载和卸载API
加载方式 | 加载路径后缀 | 异步 | 热更 |
Resource.Load | 无需后缀 | √ | × |
UnityEditor.AssetDatabase.LoadAssetAtPath | 文件后缀 | × | × |
AssetBundle.Load(LoadAsync) | .设定的ab后缀 | √ | √ |
1.Resource
Resource.Load是Unity加载Resource文件夹的加载方式,Resources文件夹会随着打包一起被打到游戏本体包内。
2.UnityEditor.AssetDatabase.Load
Editor下的加载方式,加载路径是项目下的路径,除了Resources文件夹都不会随着打包打到游戏本体内。
3.AssetBundle.Load
BuildAssetBundle包到SteamingAsset可以用于热更资源。
1.Unload(true)
2.Unload(false)+ClearUnuse
异步与同步概念
同步会在一帧内完成,是卡帧执行的,异步会分为多帧。
异步转同步
在简单的情况下,正在异步的资源,使用同步加载,似乎不会有问题,资源也正常加载
但是我在项目中使用,在复杂的情况下,会导致资源加载不出,并偶尔提示already load
同步加载
不考虑Cache不考虑依赖的简单流程
0.准备
①资源路径名 bundleName="资源放置的目录/" + "资源路径" + ".AB后缀"
②实际加载使用路径 bundlePath,平台不一样,路径不一样,具体百度(如安卓Application.dataPath + "!assets/" + bundleName)
1.加载要使用的AB 关键API:AssetBundle.LoadFromFile
2.加载Asset 关键API:AssetBundle.LoadAsset
考虑Cache的流程
关于Cache:
1.总是在AB加载完后Cache(bundlePath)
2.转场景清除Cache
3.转场景有不删除的cache列表(使用的是asset路径)
加载流程正文:
0.准备
①资源路径名 bundleName="资源放置的目录/" + "资源路径" + ".AB后缀"
②实际加载使用路径 bundlePath,平台不一样,路径不一样,具体百度(如安卓Application.dataPath + "!assets/" + bundleName)
1.是否Cache了bundlePath的Obj 是→则直接return使用 否→继续下面步骤
2.获取加载要使用的AB依赖的AB
3.加载依赖AB(总是尝试Cache)
4.加载要使用的AB(总是尝试Cache)
5.加载Asset
6.CacheObj
7.卸载要使用的AB
有没CacheObj
①↓有 CacheObj
retruen CacheObj
②↓无 CacheObj
isAssetBundleCache有没AB
↓有
GetAssetBundleCache 获得Cache的AB
LoadAssets
↓无
LoadDependences 加载依赖
↓
isAssetBundleCache 是否有CacheAB ↓
↓无 ↓
完事了才能LoadFile ← ← ← ↓
↓
LoadBundle -- LoadFile
↓
CachedDependences 策略保存依赖AB
↓
LoadAsset - GetObjectName(name);
↓
UnLoadAB
↓
CacheObject
Resource异步加载问题
1.启动协程异步加载
2.正在加载中
3.协程还在加载 但立即要使用了 这个时候不能使用同步Load
问题1
如果不停止协程 就进行同步Load 则闪退
问题2
如果停止协程(并且删除了assetResources.UnloadAsset(XXX as TextAsset)) 使用同步Load没问题 但如果马上Instan 则闪退
结果:
如果停止协程 可以马上Load 但是要下一帧才能Instan 则不能达到同步的效果
StopCoroutine(loding);
if (mLoadingResource.ContainsKey(path))
Resources.UnloadAsset(mLoadingResource[path].asset as TextAsset);
DestroyImmediate(mLoadingResource[path].asset,false);
路径
Editor:
Application.dataPath: 绝对路径/Assets
Application.streamingAssetsPath 绝对路径/Assets/StreamingAssets
Application.persistentDataPath C:/Users/Administrator/AppData/LocalLow/componyname/gamename
————————————————
iOS:
Application.dataPath /var/containers/Bundle/Application/app sandbox/xxx.app/Data
Application.streamingAssetsPath /var/containers/Bundle/Application/app sandbox/test.app/Data/Raw
Application.temporaryCachePath /var/mobile/Containers/Data/Application/app sandbox/Library/Caches
Application.persistentDataPath /var/mobile/Containers/Data/Application/app sandbox/Documents
————————————————
Android:
Application.dataPath /data/app/package name-1/base.apk
Application.streamingAssetsPath jar:file:///data/app/package name-1/base.apk!/assets
Application.temporaryCachePath /storage/emulated/0/Android/data/package name/cache
Application.persistentDataPath /storage/emulated/0/Android/data/package name/files
————————————————
Windows:
Application.dataPath: 应用的appname_Data/
Application.streamingAssetsPath: 应用的appname_Data/StreamingAssets
Application.temporaryCachePath: C:\Users\username\AppData\Local\Temp\company name\product name
Application.persistentDataPath: C:\Users\username\AppData\LocalLow\company name\product name
————————————————