Bundle包指针越界 Position out of bounds
开荒前言
掰一掰手指,今年已经是在游戏行业默默耕耘的第六年了。不经感叹时间过得好快,感觉自己每天忙忙碌碌却又好像没有留下过什么痕迹。回想起刚工作的时候就想要写个博客来记录成长的点点滴滴,却总因为各种琐事和偷懒的理由搁置了。一路走来有过挫折也有过很多次想要放弃的念头,但更多的还是解决一个又一个问题后的成就感。道阻且长,行则将至 行而不辍,未来可期。现在开始其实也不算晚,毕竟每一天都是未来的日子中最年轻的一天了。 从今天起写下一些文字,记录工作中遇到的各种问题,送给的每天进步的自己,也送给最好的你们。
关键词
- Mismatched serialization in the builtin class ‘AssetBundle’.
- The file ‘archive:/CAB-xxxxxx/CAB-xxxxxx’ is corrupted! Remove it and launch unity again!
- [Position out of bounds!]
问题情境
在版本热更新以后有极少数玩家无法正常打开游戏,游戏运行到某些特定场景会触发闪退。清除缓存或者重新安装后可以解决问题,正常登陆游戏。
任务拆解
- 找到触发条件
- 快速解决生产环境的问题,缩小影响范围
- 本地修复这个bug,在下个大版本更新时彻底解决这个问题
行动方法
碰到闪退的问题直接Bugly后台翻一翻崩溃日志,发现了一条崩溃记录且正好是走过热更的版本。
这样基本可以判断是更新后某些bundle包出现了问题导致了闪退发生
-
错误记录
-
崩溃记录
现在还不能说明发生错误的bundle包是热更后引起的,需要继续找到出问题的是哪个bundle包。
这里推荐一个视频 https://www.youtube.com/watch?v=mMjcDjM8Fm8 --Assetbundle细节解析 源自2018台北游戏开发者论坛 所以这么好的教学视频国内网站都没有呢0-0
编写脚本工具解析本地bundle包
- binary2text.exe工具 和 WebExtract.exe工具 在Unity安装目录中 比如 --> D:\Unity2020.3.17\Editor\Data\Tools 注意解析bundle包工具的unity版本要和制作时的一致
- 编写批处理文件批量解析本地bundle包 我是直接用C#写了 代码见后文 双击运行AnalyzeBundleInfo.exe即可
附上使用方法
附上C#代码
//用ide编译一下成exe即可
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
namespace AnalyzeBundleInfo {
internal static class Program {
static string strCurrDirPath => System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
static string strAssetBundleInfoDirPath => Path.Combine(strCurrDirPath, "AssetBundleInfo");
static string strAssetbundleToolPath => Path.Combine(strCurrDirPath, "WebExtract.exe");
static string strBundleTextToolPath => Path.Combine(strCurrDirPath, "binary2text.exe");
static string strExtractBatchPath => Path.Combine(strCurrDirPath, "work.bat");
static string strAnalyzeBatchPath => Path.Combine(strAssetBundleInfoDirPath, "work.bat");
public static void Extract() {
var arrFiles = Directory.GetFiles(strCurrDirPath);
arrFiles = arrFiles.Where(s => !Path.HasExtension(s)).ToArray();
var stringBuilder = new StringBuilder();
for (int i = 0; i < arrFiles.Length; i ) {
var file = Path.GetFileNameWithoutExtension(arrFiles[i]);
stringBuilder.AppendLine($"{strAssetbundleToolPath} {file}");
}
File.WriteAllText(strExtractBatchPath, stringBuilder.ToString());
WorkCmd(strExtractBatchPath);
}
public static void CollectFile() {
if (Directory.Exists(strAssetBundleInfoDirPath)) {
Directory.Delete(strAssetBundleInfoDirPath, true);
}
var dirs = Directory.GetDirectories(strCurrDirPath);
Directory.CreateDirectory(strAssetBundleInfoDirPath);
for (int i = dirs.Length - 1; i >= 0; i--) {
var newFiles = Directory.GetFiles(dirs[i]);
var abName = Path.GetFileName(dirs[i]).Substring(0, Path.GetFileName(dirs[i]).Length - 5);
newFiles = newFiles.Where(s => Path.GetFileName(s).ToUpper().StartsWith("CAB-")).ToArray();
for (int j = 0; j < newFiles.Length; j ) {
var strTargetFile = newFiles[j];
var strFileName = Path.GetFileNameWithoutExtension(strTargetFile);
var strExtName = Path.GetExtension(strTargetFile);
var strFinalName = $"{strFileName}_{abName}{strExtName}";
File.Copy(strTargetFile, Path.Combine(strAssetBundleInfoDirPath, strFinalName));
}
Directory.Delete(dirs[i], true);
}
}
public static void AnalizeBundleInfo() {
var newFiles = Directory.GetFiles(strAssetBundleInfoDirPath);
newFiles = newFiles.Where(s => Path.GetFileName(s).ToUpper().StartsWith("CAB-") && !s.EndsWith(".resS")).ToArray();
var stringBuilder = new StringBuilder();
for (int i = 0; i < newFiles.Length; i ) {
var file = Path.GetFileName(newFiles[i]);
stringBuilder.AppendLine($"{strBundleTextToolPath} {file} -detailed -hexfloat");
}
File.WriteAllText(strAnalyzeBatchPath, stringBuilder.ToString());
WorkCmd(strAnalyzeBatchPath);
}
static void WorkCmd(string batFile) {
var startinfo = new ProcessStartInfo(batFile);
startinfo.UseShellExecute = true;
startinfo.ErrorDialog = true;
startinfo.CreateNoWindow = true;
startinfo.WorkingDirectory = Path.GetDirectoryName(batFile);
if (startinfo.UseShellExecute) {
startinfo.RedirectStandardOutput = false;
startinfo.RedirectStandardError = false;
startinfo.RedirectStandardInput = false;
}
else {
startinfo.RedirectStandardOutput = true;
startinfo.RedirectStandardError = true;
startinfo.RedirectStandardInput = true;
}
var p = Process.Start(startinfo);
p.WaitForExit();
}
public static void Main(string[] args) {
Extract();
CollectFile();
AnalizeBundleInfo();
}
}
}
比对检查结果
-
找到了对应热更出错的bundle包
-
在运维svn中比对找到了热更包里的确有这个文件
-
猜测是热更包下载之后在安装环节产生了IO错误 类似在进行IO写入时本地bundle包并未卸载干净 导致bundle包头文件记录的内存地址与实际文件地址不相吻合从而引发了闪退
结果措施
- 后续版本不不热更部分资源(在热更新前被引用到的资源) 相应需要热更的部分尽量用lua代码去改
- 继续确认是IO发生了错误还是说老的bundle没有卸载 缓存的头文件地址成了野指针
- 优化一版热更流程
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgiffia
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13