Tips:
0 Unity的PlayerSettings的otherSettings里面的Enable Exceptions里面选择Full StackTrace ,可以在打出的包中的浏览器的webgl打印出错误调用栈
1 一般出现了错误 可以看看在浏览器里面传的变量和在编辑器里面的有什么不一样
如果有不一样 就可以试着将浏览器的变量放入到编辑器里面试试
2 有时一些错误比较可能是浏览器的缓存问题 适当清空缓存是可以的
3 有时一些错误在一个浏览器表达不明确 可以换个浏览器 比如谷歌和火狐切换
4 如果浏览器出现了很不明确的错误提示甚至导致崩溃,而且编辑器本身也有一些无关痛痒的错误,第一时间将这些无关痛痒的错误解决了。因为这些错误可能就是造成浏览器崩溃的错误。
5 开一些软件也可能造成和服务端的一些资源加载不过来
6 有些错误是在Unity WebGL 程序还没加载完成就出现的 自己清缓存加上服务器重启可能可以了 即使自己一直找不出哪里的错
7 有时打不了包可能是因为系统盘满了
8 在浏览器出报错的时候,有时会出现很长的报错信息,但是真正有用的部分可能不是那个很长的,可能是很长的前面或者后面出现的报错信息,所以看报错的时候全部认真看是很重要 的
9 如果有些bug确定处理好了 但是浏览器还是老样子,可以清一下浏览器缓存
错误:
1 RuntimeError: index out of bounds
这种错误出现,可能是在编辑器里面是 Object reference not set to an instance of an object
即访问某个空引用。
2 An error occurred running the Unity content on this page. See your browser JavaScript console for more info. The error was:
SyntaxError: expected expression, got '<'
在我的项目里 这并不是 真的出现了某个符号错误 而是在webgl程序刚加载的时候 就开始接受浏览器或者前端传入的字符 在传入的字符对于一些数据的读取 工作来说 是错误的时候 就会出现这样的报错了 言简意赅就是前端和unity程序交互的时候,传入的某个定好的字段如id是错的。
第二种原因可能是 新推上去的项目还在更新 还没有更新完成
3 有时我们在浏览器运行的时候,可能会遇到一些错误 但是在unity编辑器的时候,不会遇到,这类abort错误可能是空指针异常。像这样的看不明白是什么错的只能自己去排查了
因为在编辑器都是正常的 没办法直接看 在我的项目中这个问题的出现 我首先用的是夹逼法 将项目推到刚好不会出现这个报错的时候 当然这需要每一次选版本都要重新打包 看浏览器是否正常 选择了之后 查看下一个项目和这个项目之间有什么区别 查看代码之后发现没有什么地方会引起这种错误的 只是有个隐藏的bug 但是不足以导致这样的崩溃。然后我发现程序有个空url加载的报错 但是这个报错一直无关痛痒 在刚好不会出现上面这个报错的时候 编辑器也有啊 但是我实在找不到有什么错了,就干脆回到最新的版本将这个解决了 然后解决之后 unity打包选择的是不压缩 因为采用的是夹逼法,所以我选择不压缩的时候打包速度会快很多,并不是因为不压缩能解决这个问题。然后最新版打包出来就不会有这个报错了.
所以有时有一些编辑器的报错要及时解决 虽然短时间内在浏览器和编辑器无关痛痒,但是可能后续改了某些代码之后 在浏览器就出现报错了。
说白了 那个代码为232的报错是我用unityWebRequest加载某个网络ab包的时候 发了个空地址导致的报错 导致UnityNetWorkError 后面可能在浏览器端导致的是某个空引用,在unity编辑器什么事都没有
4
在我的项目里面 这个报错的原因是 因为后端服务器是阿里云 阿里云为了让速度快些 就会启用高程度的缓存
但是缓存程度太高了 导致有时新的内容更新不上去 就会报这个错 清理一下缓存就可以了
5 WebGL打包不了 有可能是UI里面设置了两种字体
6 WebGL打包出来的字体显示不了中文 可能是选择了Arial字体 这个字体在浏览器的WebGL里面是显示不出来中文的
7 json反序列化报错
“Newtonsoft.Json.JsonSerializationException unable to find constructor to use for types” error when deserializing class
这个方法的一个原因是勾选了某个选项导致在没有默认初始化生成一个类的情况下,系统在打包的时候会将这个类的空构造方法取消掉
然后JsonConvert.DeserializeObj的时候 会找不到空构造方法 我尝试了在代码里面使用空构造方法new一个 但是打包出来的程序在浏览器端会报下面错误 所以就没有继续了
NotSupportedException: System.Reflection.Emit.DynamicMethod
单纯使用Newtonsoft.json在webgl的浏览器端会有il2cpp的访问问题,这里推荐使用的是JSON .NET For Unity
可以解决这个问题 或者去官网下载最新的Newtonsoft插件,最新的插件现在到12.0.3左右,在WebGL上面的序列化和反序列化可以正常支持
参考链接
“Newtonsoft.Json.JsonSerializationException unable to find constructor to use for types” error when deserializing class
8 浏览器加载不了webgl 报某个错
可能找了很久发现没有什么地方是错的 原因可能是在编辑器那里已经存在很久了的 觉得无关痛痒的一个报错
我这边有个例子就是url为空的报错 解决了之后重新打包就可以进去了 所以有小错误要及时解决
还有个要注意的地方就是下面红框里设置为None的话 如果加载过程中出现 错误 会中断加载的过程,没有什么大报错
将Development Build设置为false 然后将选项设置成下图就行了
9 Screen position out of view frustum (screen pos 0.000000, 0.000000, 1000.000000) (Camera rect 0 0 0 0)
我遇见这个问题是在webgl上面, WebGL上面切换切卡的时候,需要把嵌入的U3D程序给屏蔽了,但是没有真正关掉,这种时候如果只是单纯前端切换切卡页面,对U3D嵌入程序什么操作都没有做,每帧都会报上面那个错误,要及时把Camera.enabled设置为false,参考网站
Hidden Unity WebGL App: “Screen position out of view frustum”
上述解决办法有个很大的弊端:第一种就是需要前端及时与U3D程序内部进行交互,假设U3D加载好之后会向前端访问当前切卡是否关闭, 如果在第一次U3D程序正在加载的时候,切掉,然后又切回来,这时其实已经有两个U3D程序了,只是其中一个看不到,这时第一个加载好之后询问是否已关闭但是没有 则没有设置camera,这时又没有显示,则会报错,新建一个全局字典,对于每个加载的U3D程序作为键,切卡是否已关闭作为值进行存储,当有U3D程序询问的时候,就返回以它为键的值,这种做法因为前端语言的局限性也不是那么好做
还有种说法是不要真的把U3D所在的页面切了,只是把点击的切卡的页面新加上去 ,这种做法的弊端就是如果用户多次点击U3D程序所在的切卡则会造成多次加载,太多会导致内存泄漏浏览器崩溃,Application.Quit在WEBGL端又无效
这里介绍个更加方便的解决办法:如下图
WEBGL打出来的包有很多函数可供调用,只是之前自己一直以为是前端的所以没注意,
其中常用的就有onprogress,可以根据里面的加载进度值自定义加载画面,前端与unity交互的SendMessage出自此处,
当然有些方法是否有效还是要试下,比如SetFullscreen在一些时候就不能全屏
这里用到的是Quit方法,如果程序加载过程中和完成后前端都会有个对象,如果unity程序已经完成了加载,通过这个对象调用Quit会立刻摧毁unity在浏览器的程序,如果程序未加载完成时候调用,程序加载完成后会自个销毁,切卡切换卸载U3D程序是很符合逻辑的,因为切卡换了时候程序还在的话,会比较吃机器,但是这种quit方法并不会真的清理掉程序的内存
10 The type name ‘PoseData’ could not be found in the namespace ‘UnityEngine.XR.Tango’ 这个是我将unity升级到2019.3.1f1版本之后出现的,解决办法就是在Window->PackageManager里面降XR的包移出或者升级到最新,参考网址
11 如果WebGL打包不了但是一直查找不到原因,尝试重启unity,如果还不行尝试重启电脑,我试过几次这样的,这可能是unity的bug
12 在谷歌浏览器报错
VM12 UnityLoader.js:4 GET http://192.168.1.39:8082/static/Build/CPWEBGL.json 404 (Not Found)
在火狐浏览器报错
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON dataUnityLoader.js:4:9722
onload http://192.168.1.39:8082/static/Build/UnityLoader.js:4
情况是这样的, 所有前端引用的都是我同一个unity打包的webgl程序,在前端的用户部分能正常访问,前端的商家部分报错找不到这个,其实我和前端约定叫做CPWEBGL,我少放了B,导致商家部分找不到我的文件,但是前端的用户部分能正常访问我也不清楚前端做了什么骚操作,这次经历给的经验就是要注意打的webgl程序的名字
13 LinkError:“TellForEndGoToChatNow"import object field is not a Function”,WebGL里面这个出错是因为在unity的自定义前端交互函数文件Mktail.jslib里面定义了这个方法如红框但是这个方法里面的绿框框住的某个前端方法没有定义,虽然说函数只是在C#里面定义了这个外部引用函数,一直没到调用时机,但是mktail.jslib里面的方法估计在程序加载时候才进行错误检查,发现前端的GotoCustomChat函数没有定义过,所以不认为TellForEndGoToChatNow是一个方法,所以进行的报错吧
public class HallProSurGoUI : MonoBehaviour
{
#if UNITY_WEBGL
[DllImport("__Internal")]
private static extern void TellForEndGoToWangPu();
[DllImport("__Internal")]
private static extern void TellForEndGoToChatNow(string sellerId);
#endif
14 missing function: canZhanGetWebGLUserId 这个报错出现的原因是在unity的自定义前端交互函数文件Mktail.jslib里面没有定义canZhanGetWebGLUserId 这个方法但是在c#文件里面引用到了这个方法
c#定义
[DllImport("__Internal")]
private static extern void canZhanGetWebGLUserId (string sellerId);
15 如果项目有在WebGL端运行的情况,通常会在Unity工程的Assets下的Plugins文件夹里面有自定义的jslib文件,这个文件里面每个定义的方法后面要有逗号分开,如果有没分开的,可能会导致webgl平台的unity程序生成失败
mergeInto(LibraryManager.library, {
//获取产品id
getProductIdStrFromJSCode: function(){
console.log("jslib getProductIdStrFromJSCode " + window.getModelIdFromJSCode());
var id = window.getModelIdFromJSCode();
var bufferSize = lengthBytesUTF8(id) + 1;
var buffer = _malloc(bufferSize);
stringToUTF8(id, buffer, bufferSize);
return buffer;
},
});
16 和上面的内容类似的,jslib文件里面写到代码要符合javascript即js语法的规则,js是脚本语言,和lua类似,定义方法参数的时候不能够定义类型,如果在WebGL打包失败的时候,报错指定到了jslib所在的内容,例如
Unexpected identifier,,SyntaxError: Unexpected identifier at Object.load (eval at globalEval
reprocessed source (you can run a js engine on this to get a clearer error message sometimes)
一般是里面的内容不符合js语法的规则,这时可以将jslib里面的代码复制,放到网页上的某个js脚本语法检查网页
17 Access to XMLHttpRequest at ‘’ from origin ‘https://seller.pre.mktail.cn’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
这个问题出现的原因是浏览器的同源策略问题,浏览器的同源策略会屏蔽掉一些非同源网站的请求,所以U3D发出的网络请求会被浏览器给阻隔掉
解决前端跨域:has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header…
18 在unity工程的 .jslib文件中,某个函数如果传字符串到外面,会像下图中的红框内部这样定义,这里说明一下,字符串参数为啥要用Pointer_stringfy处理,其实在c#传字符串给js的过程中,jslib里面的 js接收到的是字符串在内存中的地址,既然是地址的话,转换成字符串就需要Pointer_stringfy再处理一下,这样传到外面的才是真的字符串
19 关于unity程序结束的方法,目前unity在WebGL上面还不是很成熟,感觉还是有点bug,其中有个比较严重的就,程序在结束之后内存没有清除,这个bug unity官方在2018年中的时候在论坛 Unload Unity gameInstance and release heap memory 上面也承认了,目前的2019年中记录的解决方案参考下面网址
完全释放Unity WebGL内存
它的做法是将unity程序嵌套在iframe里面
可行性不清楚,我同事试了说不行,但是在这之前找过很多方法了,都是不行的,这里记录一下这种方法的存在。
20 WebGL打包报错 Unknown format, not a static library!
我这里是
stdout:
stderr:ERROR:root:D:\UnityProjects\Company\Assets\Company\ExhibitionHall\Origin\AVProVideo\Plugins\iOS\libAVProVideoiOS.a: Unknown format, not a static library!
原因是引用了AVPro这个插件,但是里面的ios第三方库libAVProVideoiOS.a设置成了AnyPlatform,导致WebGL打包的时候需要考虑这个库 ,但是识别不了,将识别平台改成ios即可
21 对于在jslib里面要获得前端函数的stiring类型的返回值,获得了之后需要有下面四行代码:
var bufferSize = lengthBytesUTF8(id) + 1;
var buffer = _malloc(bufferSize);
stringToUTF8(id, buffer, bufferSize);
return buffer;
c#才能接收到字符串
mergeInto(LibraryManager.library, {
//获取产品id
getProductIdStrFromJSCode: function(){
console.log("jslib getProductIdStrFromJSCode " + window.getModelIdFromJSCode());
var id = window.getModelIdFromJSCode();
var bufferSize = lengthBytesUTF8(id) + 1;
var buffer = _malloc(bufferSize);
stringToUTF8(id, buffer, bufferSize);
return buffer;
},
});
22 在WebGL端报错 Scene ‘DesiginSpace’ couldn’t be loaded because it has not been added to the build settings or the asset bundle has not been loaded. To add a scene to the build settings use the menu File->Build Settings ,
其实我在buildsettings里面是添加了DesiginSpace这个场景的,后来我几次将这个场景的位置调上或者调下都没效,发现场景名和存储场景路径中的某个文件夹名字一样, 就试着将场景名字改了一下,后面加个Scene,然后就可以了,估计是unity的bug。
StackOverflow也有人遇到了这样的错
How Do I Load A Assets Bundle
他的解决办法是重新将场景从build settings里面移出然后再添加进去
这个bug算是unity的bug了,我在关于unity的bug中也记录过
Unity 引擎报错集锦
因为在webgl出来的,其他人可能在webgl也会遇到,所以这里也说一下
23 unity的一些静态放置的UI在浏览器可能出现异常情况,对于这种问题需要在运行的时候将这种出现异常情况的UI用代码的方式进行设置。
24 missing function: _ZNSt2___212basic_stringIcNS_11char_traitsTcEENS_9allocatorIcEEE6__initEPKcj这个报错的出现的原因一般是某个第三方库缺少引用或者是双重引用,我这边的情况是我使用了TriLib插件后,导出没问题,但是导出的包运行的时候报这个错误,因为我使用的Trilib插件是阉割版的,它的WebGL的分支不存在,导致在WebGL的时候出现了这个错误。出现这种错误看不见他具体报错内容而是一堆乱码的时候,要想想最近做了什么,最后一个可行的分支版本与出错版本的最显著区别是什么地方,我这次的错误靠的是这个方法猜出来的。
下图的左边是正常版本的,右边是阉割版本的,可以看出严格版本里面没有WebGL这个分支
25这次遇到的还是关于Trilib插件的问题,在使用trilib1.8.7,并且在导出WebGL包的时候报错 unity版本是2019.3.1f1
Linking globals named ‘gzgetc’: symbol multiply defined!ERROR:root:Failed to run llvm optimizations:
参考链接: Unity 2019.1 TriLib WebGL build failed
链接的陈述大概是 插件里面的库文件对gzgetc的定义和unity的打包的库文件对gzgetc的定义重复了
如图所示
我没有按照链接里面的做,将trilib版本从1.8.7升级到了1.9.0,它里面的内容也变了
这次打包的时候就不报错了
26
Failed running “E:/AllUnity/2019.3.1f1/Editor/Data/PlaybackEngines/WebGLSupport\BuildTools\Emscripten_Win\python\2.7.5.3_64bit\python.exe” -E “E:/AllUnity/2019.3.1f1/Editor/Data/PlaybackEngines/WebGLSupport\BuildTools\Emscripten\emcc” @“D:\UnityProjects\Company\Assets…\Temp\emcc_arguments.resp”
stdout:
stderr⚠️ unresolved symbol: FullScrnForEndClickERROR:root:‘E:/AllUnity/2019.3.1f1/Editor/Data/PlaybackEngines/WebGLSupport\BuildTools\Emscripten_FastComp_Win\binaryen\bin\asm2wasm D:\UnityProjects\Company\Temp\StagingArea\Data\linkresult_wasm\build.temp.asm.js --total-memory=33554432 --trap-mode=clamp -O3 --mem-init=D:\UnityProjects\Company\Temp\StagingArea\Data\linkresult_wasm\build.js.mem --mem-base=1024 --wasm-only --symbolmap=D:\UnityProjects\Company\Temp\StagingArea\Data\linkresult_wasm\build.js.symbols -o D:\UnityProjects\Company\Temp\StagingArea\Data\linkresult_wasm\build.wasm’ failed
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
这个报错是在打包时候报的错,仔细看内容,在里面有段话 stderr⚠️ unresolved symbol: FullScrnForEndClick 这个是关键的,
在我的工程里面,这个报错的原因是在jslib文件里面没有定义 FullScrnForEndClick 这个方法,但是在c#文件里面有引用到
#if UNITY_WEBGL
[DllImport("__Internal")]
private static extern void ForEndFullScrn();
[DllImport("__Internal")]
private static extern void FullScrnForEndClick();
#endif
所以把引用的去掉就可以了 ,或者在jslib里面定义这个方法