|
最近几天都要处理一个 Unity AssetBundle 打包问题,花费了很多时间和精力,搜索引擎上也查询不到太多相关内容,特此记录一下
搜索关键词:
Failed to replace file
Moving Temp/unitystream.unity3d to
<hr/>传统(非 SBP)Unity 构建 AssetBundle 一般是通过 BuildPipeline.BuildAssetBundles 来触发
这里又分两种:
// 1. 让 Unity 通过在 Editor 中标记的 AssetBundleName 来打包
public static AssetBundleManifest BuildAssetBundles(
string outputPath,
BuildAssetBundleOptions assetBundleOptions,
BuildTarget targetPlatform)
// 2. 指定 AssetBundleBuild 数组来构建
public static AssetBundleManifest BuildAssetBundles(
string outputPath,
AssetBundleBuild[] builds,
BuildAssetBundleOptions assetBundleOptions,
BuildTarget targetPlatform)
因为现有资源采用的是第 1 种(不好的预感。。),这里也讲解下这种方式
示例
可以通过文件夹标注来定义,已文件夹内的所有资源打成一个包,在 Stream 上发行的 Unity PC 游戏大部分都是采用这种方式。
这种方式的好处的是:便于管理,PC 上内存也大,启动时直接加载所有 bundle, 内存占用个 1-2 G 问题也不大
同样也会带来问题:随着资源越来越多,打一次包很慢(折磨),如果你仅仅修改了 1-2 个资源,也需要重新编译,如果你不幸的没有打包机,那每个人打出来的资源计算的 md5 还不一样(折磨2)。如果你是移动端,基本告别了这种打包方式,因为单个 bundle 过大会导致你的内存飙升,也不利于做资源更新(折磨3)
巧的是,我目前做的项目采用了第 1 种方式,但是又不想等待太多时间,并且又不幸的没有打包机(debuff 叠满),我需要寻找一种可以单独某个文件夹内所有资源的方式,减少打包时间
<hr/>我列出了几个方案:
方案1:对单个文件夹打成一个 bundle
失败原因:文件内有依赖其他文件夹内容, 如果强行打会造成 bundle 变大
方案2(重点卡住):计算目标文件夹的依赖, 得到需要打的bundle, 比如 game 依赖了 common, 就和 common 一起打
但是以此为根据的打包后, 在最终输出阶段会提示
Failed to replace file xxxx
Moving Temp/unitystream.unity3d to 拒绝访问。。
多次尝试后发现是 unity bug, 最后 unity 自带的 manifest 文件应该会输出到上面目录下, 并且命名为 文件夹名字.manifest, 但是这个问题是因为, 他直接把目录当前文件路径去输出, 导致输出失败, 因为当前路径是一个已经存在的文件夹
方案3:对每个 AssetBundleBuild 添加一个 variant name 为 __tag__to_remove, 可以正常输出了
但是在多次打包后, 会导致正常的 bundle name 被替换 ${name}.__tag__to_remove, 导致在打包前检测是否含有这个 bundle 是失败
<hr/>经历过以上的种种方案的折磨后,依然是不能单独打一个文件夹,这是我已接近崩溃
后续尝试了修改 BuildAssetBundleOptions 的值,依然不行
直到!! 我修改了 AssetBundleBuild 种的 assetBundleName,之前是命名为 Editor 种已经存在的 (已经被为文件夹使用了)
w_wrist_001 assetBundleName 与 文件夹名相同
修改为:assetBundleName = bundleName + &#34;__to_remove_tag.ab&#34;
终于,它能正常打出来了!!!
<hr/>总结:
构建 AssetBundle, 不要两种方案混合用(我这是没办法= =)
以及最好使用第二种方案 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|