找回密码
 立即注册
查看: 635|回复: 15

Puerts Inspector指南(一)在UE4和Unity里调试Javascript

[复制链接]
发表于 2024-1-19 14:14 | 显示全部楼层 |阅读模式
下文所有“调试”字眼包罗但不限于代码调试,也指代性能profile、内存分析之类法式开发过程中容易用到功能
零、简单的目录

本文包罗以下内容。可能可以解答你以下疑问。
一、前言
二、V8 调试器道理是什么 ?
三、隔壁大哥 Node.js 是怎么用调试器的啊?
四、Puerts 怎么启动调试 ?
五、怎么连上调试器 ?
六、手机怎么调试 JS  ?
<hr/>一、前言

俗话说,“能用Javascript做的事情最终城市用Javascript做”。
Javascript之所以强大,除了它的再生父母Google V8在性能上带来的贡献外,离不开它和Chrome Devtool联手提供的强大的调试能力。
一个强大的Devtool,可以减少开发者们无数的脱发加班时间。加班少了,幸福感高了,自然才有JS生态今天的强大。(划重点:加班少了,自然会强大)。
作为JS生态的拥护者,Puerts(读作普洱TS)积极地把V8的调试能力带入主流游戏引擎的脚本开发中,本系列文章,就会为你介绍使用Puerts的过程中调试JS的方式。
<hr/>二、简单的储蓄常识 —— V8调试器是怎么运行的

暂且非论JS和V8,放眼市面上所有语言的调试需求,大略都可以如此归纳

  • 你在调试器上执行操作(执行代码段等),通知法式作出相应措置,返回成果。
  • 你的法式发生了一些事件(命中断点,打印Log等),通知调试器展示成果。
为了满足这两种需求,同时让调试器和执行法式能解耦(最终发布的法式很可能需要不包含调试器,以节省包大小),大师遍及城市使用类似C/S的架构实现调试处事。



   右边这位薯条鸽子是client,它法式崩溃,并不会影响左边充任server的鸽子的运行

V8的调试也不例外地采用了这样的架构,而且它使用了Websocket来实现C/S之间的通信。
在V8/Chrome的实现里,逻辑法式充任调试的server,调试器充任client。当它们互相联通之后,就能不竭地把法式的调试信息展示在开发者面前。



我们在chrome打开网页的时候,devtool就是用websocket和运行网页的V8通信的

V8采用websocket带来了许多好处。
一是因为它属于明文协议,易于理解,非常便利开发者实现他们本身的调试器,比如除了Chrome Devtool之外,VSCode也有Javascript调试器。
二是因为websocket基于网络,开发者可以很容易地跨设备对V8进行调试。微信小法式的长途调试能力就是基于此完成的,后文也会提到使用puerts的过程中如何进行手机调试。
<hr/>三、简单的参考知 识 —— Node.js是怎么使用调试器的

在讲述如安在puerts里启动Javascript调试之前,我们先看看另一个著名Javascript Runtime——Node.js是怎么使用调试器的。如果你不知道Node.js是啥,这里就先提醒你去知道一下,因为要阐扬Javascript生态的力量,就不能分开Node.js。
Node.js为开发者提供了两个跟调试器有关的参数。



你可以通过node -h查看到它们

前面提到,V8的调试模型里,执行法式本身充任调试server。这里提到的两个inspect参数,就是用来在法式启动时告诉V8:“务必把调试server启动起来。”
Node.js启动调试server之后,开发者就能通过chrome的chrome://inspect找到调试server并调试。

那么--inspect和--inspect-brk有什么区别呢?
很显然,server和client不是一个鸡生蛋蛋生鸡的问题,永远是先有server再有client,逻辑才能成立。
如果法式开始执行和server启动是同时的,那么在开发者的client连接上之前,法式必然有一些部门已经执行过了,开发者无法调试到它们。
所以,V8提供了一个“等待调试器连接”的能力,一旦启用,法式就会等到开发者调试器连接上后,才会往下执行,这样开发者就能调试到法式的开头部门了。
Node.js的--inspect-brk以及后面提到Puerts的WaitDebugger就是打开这个开关用的。

<hr/>正题开始

四、启动调试

正如前文所说,要调试Javascript,就要先让V8把调试server启动起来。Puerts里让V8启动调试server也非常简单,基本就是多传一个参数的事情。
Unreal Engine 4里启动


  • 为默认JS虚拟机启动调试server
在UE菜单上选择“编纂->项目设置”,打开设置页面后在“插件->Puerts Setting”页面中开启调试以及设置端口


2. 为本身创建的JS虚拟机启动调试server
GameScript = MakeShared<puerts::FJsEnv>(
    std::make_unique<puerts::DefaultJSModuleLoader>(
        TEXT(”JavaScript”)
    ),
    std::make_shared<puerts::FDefaultLogger>(),
    8080 // 指定调试websocket server所用的端口,即视为要打开调试server
);
// WaitDebugger的感化参见前文的参考常识
// GameScript->WaitDebugger();
GameScript->Start(”QuickStart”, Arguments);Unity3D里启动

void RunScript()
{
    jsEnv = new JsEnv(
        new DefaultLoader(”E:/puerts_unity_demo/TsProj/output/”),
        8080
    );
    // WaitDebugger的感化参见前文的参考常识
    // await jsEnv.WaitDebuggerAsync();  // 如果c#版本高于7.2(撑持async/await),建议用异步等待,否则用同步阻塞等待
    // jsEnv.WaitDebugger();
    jsEnv.Eval(”require(&#39;QuickStart&#39;)”);
}

void onUpdate()
{
    jsEnv.Tick(); // 不加这句的话,会发现inspector跑着跑着就没反映了
}同时你需要把Unity的“Edit/ProjectSetting/Player”菜单里的“Resolution and Presentation/Run In Background”勾选上,否则切换到调试器窗口之后,unity就遏制了。
<hr/>五、连接调试器

调试server启动之后,接下来就是把调试client连接上去并开始调试了。正如前文所说,目前有两个主流的调试器可供我们使用:Chrome Devtools和VSCode。
用Chrome DevTools调试本机Javascript环境

方式一:添加 discover target

    • 在chrome里打开chrome://inspect,点击Configure...



    2. 添加你的调试server的端口,ip使用127.0.0.1代表本机


    3. 点击inspect即可打开devtool窗口进行调试。



方式二:直接使用inspector.html
在chrome地址栏输入以下url(ws参数为调试处事器的ip和端口)即可直接打开一个devtool页面
devtools://devtools/bundled/inspector.html?v8only=true&ws=127.0.0.1:8080



用VSCode调试本机Javascript环境

    1. 在VSCode的此处选择create a launch.json file


    2. 这里先随便选一个


    3. 在右侧界面再选择 add Configuration


    4. 在弹出的菜单里选择Node.js: Attach


    5. 在port处填入你传给puerts的调试处事器端口


    6. 回到左侧选择Attach而且点击播放按钮


    7. 进入这个状态,就是开始调试了。


<hr/>六、手机调试

        前面提到,V8采用websocket这样的网络协议来实现调试通道,非常便于实现长途设备调试。
        只要你的工作电脑手机处在同一局域网内(超大公司的特殊网络环境除外),都能非常便利的实现调试client和调试server的连接。
        需要注意的是,puerts官方为了保证安全性,默认没有打开手机版本puerts的调试开关,你需要在CMakeLists.txt里添加以下代码,并从头编译puerts才可以使用调试能力。
target_compile_definitions (puerts PRIVATE WITH_INSPECTOR)Chrome

只需要在添加discover target的时候,ip填入手机在局域网内的ip即可


又或者是使用inspector.html时,ws参数填手机在局域网内的ip。
devtools://devtools/bundled/inspector.html?v8only=true&ws=192.168.1.2:8021
VSCode

在Add Configuration时,可以选择Attach to Remote Program


address处填入手机的局域网ip即可


网络环境复杂的情况

        前面提到了某些超大公司的网络环境斗劲特殊,不必然允许工作电脑与手机直接进行网络连通(比如笔者地址的腾讯)这时候怎么办呢?这时候就可以掏出你的数据线,无论是iOS还是安卓,都有东西提供“port forwarding”的能力,让你通过数据线与手机进行网络通信。
什么意思呢?
        比如你设置了当地9222端口到手机8102端口的tcp port forwarding,所有对当地9222端口成立的tcp连接城市被转发到手机的8102端口上。
        放到v8调试这个场景上,你可以理解为:你的调试client可以连接到当地9222端口上的一个debug server,但这个server实际上是手机上8102端口上的,只是颠末数据线转发了。


        至于port forwarding东西,安卓和iOS分袂使用adb和usbmuxd即可,你可以直接google它们安装。
        安装好后在命令行输入:
adb forward tcp:9222 tcp:8102 #安卓
iproxy 9222:8102 #iOS        配置好后,直接按照上文提到的“调试本机Javascript环境”的方式使用即可。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2024-1-19 14:15 | 显示全部楼层
今天配置了下VsCode调试,发现本机调试一般也应该使用远程调试的方式,一般TsProj编译的js不是放在TsProj的目录下,而是放在了Unity Assets目录下。
发表于 2024-1-19 14:16 | 显示全部楼层
进行用vscode远程调试手机,launch.json就按照你的图中的样子进行配置。但是连接上手机后,所有的断电都显示Unbound状态,没有办法命中。请问这种情况要怎么处理?不知道是不是需要进行remoteRoot配置?这个要怎么配置呢?
发表于 2024-1-19 14:16 | 显示全部楼层
我还尝试了用chrome进行远程调试,也是可以连上手机,然后在DevTool的Source标签页下,将我本地的工程目录AddToWorkSpace。然后打断点也是没法命中。
发表于 2024-1-19 14:16 | 显示全部楼层
可以传入js所处的路径的,这个有传不,可以参见demo
发表于 2024-1-19 14:17 | 显示全部楼层
远程调试的时候devtool面板内有出现你的js吗,一般不需要再AddToWorkspace的
发表于 2024-1-19 14:17 | 显示全部楼层
我也是类似上边问题,核心的js,类似timer这种,能在chrome里面打断点,但是那个demo的js就是打了断点都不能命中,是不是和生成的后缀是js.txt有关?
发表于 2024-1-19 14:18 | 显示全部楼层
大佬 FPSDemo 按照这个教程 总是无法打上断点怎么办呀 一直unbound
发表于 2024-1-19 14:18 | 显示全部楼层
大佬解决了吗我一直是unbound
发表于 2024-1-19 14:18 | 显示全部楼层
我向作者请教解决了, 是把两个JsEnv给搞混了 https://github.com/Tencent/puerts/issues/993
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-4-29 06:05 , Processed in 0.116521 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表