doc/unity/zhcn/faq.md
意思是Unity无法加载PuerTS的Native Plugin,比如windows下的.dll,macOS下的.dylib或.bundle,其它平台下的.a、.so等。
出现该问题的可能性如下:
otool、Linux下可以使用objdump,Windows下可以使用Dependencies查看NativePlugin文件的依赖。查出来后自行补充安装即可。相关issue:https://github.com/Tencent/puerts/issues/941
Puer002代表PuerTS在加载js文件时没有能够找到对应的js文件,具体来说,是调用ILoader的FileExists返回了false,或是调用IResolvableLoader的Resolve时返回了空字符串或null。
如果遇到这个问题,先确认你使用的loader是DefaultLoader(即创建JsEnv时没有传任何参数)还是你自己编写的自定义Loader。然后检查这个Loader的FileExists函数或是Resolve函数,看看为什么会返回不正确的值。
Puer003和Puer002是类似的,只不过Puer003是Loader的ReadFile接口返回了空。你同时要检查一下为什么FileExists或Resolve返回了存在,但ReadFile时却读到了空
版本号中的pre和RC:
如果你用js,可能是输错参数了。
如果你用typescript,可能是子类同名,但不同参数的函数覆盖了父类。以System.Text.Encoding.UTF8.GetBytes为例,你直接调用会报错。
System.Text.Encoding.UTF8.GetBytes("你好");
System.Text.Encoding.UTF8指向的对象System.Text.UTF8Encoding,有GetBytes的其它重载,按目前的实现找到当前类有同名函数就不再找基类导致的。这时候你可以手动指定下用其基类接口访问该对象。
Object.setPrototypeOf(System.Text.Encoding.UTF8, System.Text.Encoding.prototype);//只需要调用过一次即可。后续调用GetBytes都不用再调用。
System.Text.Encoding.UTF8.GetBytes("你好");
可能是没调用JsEnv.Tick
这是vscode,其它IDE的看各IDE的指引,按nodejs的调试来处理即可。
ts/js中调用require('./a/b')时,ILoader会被调用并传入字符串".../a/b.js"(相对rootPath的完整路径),你需要理解这字符串并(从文件/内存/网络等)加载好js文件并直接返回。而debugpath需要返回调试器可以理解的路径(比如js文件的绝对路径: D:/.../a/b.js),通过设置out string debuggpath参数返回,调试器后续根据这个文件路径来匹配文件上的断点。
Windows平台不区分文件大小写名称且使用反斜杠"\"代替"/"
你将一个js函数映射为一个delegate有时会报这错误,XXX就是要映射的delegate,可能的情况如下:
// 代码示例
Puerts.JsEnv jsEnv = new Puerts.JsEnv();
jsEnv.UsingFunc<int, int>();
System.Func<int, int> add = env.Eval>(@"
const add_func = function (num) {
return num + 1;
}
add_func;
");
Console.WriteLine(add(10));
参数数量超过4个,解决办法:官方目前只支持4个,如果有需要,可以依葫芦画瓢写更多的参数支持。
参数含ref,out的修饰,目前尚未支持,解决办法:填写issues来提需求
执行
sudo xattr -r -d com.apple.quarantine puerts.bundle
因为这些方法是编辑器独有的,可以通过filter过滤掉,filter使用参考使用手册
unity默认会进行代码剪裁,简而言之unity发现某引擎api,系统api没有被业务c#使用,就不编译倒cpp。 解决办法:1、对要调用的api生成wrap代码,这样c#里头就有了引用;2、通过link.xml告知unity别剪裁,link.xml的配置请参考unity官方文档。
往往是由于该方法/属性/字段是扩在条件编译里头,只在UNITY_EDITOR下有效,这时需要把这方法/属性/字段通过Filter标签过滤,之后重新执行代码生成并打包。(discussions说明)
默认打包后不再使用反射获取扩展函数, 可使用PUERTS_REFLECT_ALL_EXTENSION宏来开启反射.(反射速度慢, 建议在任何时候都应该生成静态代码)
GetComponent<XXX>()在CS为null,但在JS调用却不为null,为什么其实那C#对象并不为null,是UnityEngine.Object重载的==操作符。当一个对象被Destroy,未初始化等情况,obj == null返回true;GetComponent<XXX>()如果组件不存在,Unity重载==的结果也会让其返回null。但这些C#对象并不为null,可以通过System.Object.ReferenceEquals(null, obj)来验证下。
对应这种情况,可以为UnityEngine.Object写一个扩展方法,需要判空的时候统一用它解决:
public static bool IsNull(this UnityEngine.Object o)
{
return o == null;
}
import sm from 'source-map-support.gen.mjs'
sm.install({
retrieveFile: (path) => {
// 如果你用的不是inline的source-map,这里还得处理sourcemap的加载
return puer.loadFile(path).content
}
});
注意是概率报,不是必报,这种情况通常是因为多线程访问了JsEnv,可以尝试打开多线程支持,方法如下:
ps:以上是v8后端的的现象和解决方案,qjs后端如果多线程访问有可能会抛个没有文件信息的异常<unknow>:-1
ps:如果是必报,应该是js代码中有递归死循环了。
没有生成代码,请按il2cpp优化特性/使用步骤操作。