找回密码
 立即注册
查看: 321|回复: 1

UE5 PuerTS学习与实践

[复制链接]
发表于 2023-8-15 15:48 | 显示全部楼层 |阅读模式
在游戏引擎语境中,脚本语言是高级、相对容易使用的编程语言,可供用户便利地使用引擎经常用到的功能。借助于脚本语言,法式的开发者和使用者能够便利的定制一个现存的游戏。
对比更改原生法式代码,需要从头编译及链接法式,脚本语言主要有以下优势:直译、轻量、撑持快速迭代、便利易用。[1]



虚幻引擎C++编码与脚本语言编码对比

在使用虚幻引擎进行开发的过程中,UE 的蓝图脚本可以便利的改削逻辑,从头编译蓝图然后即可看到改动后的效果,这对功能验证和开发效率的提升辅佐非常大。对于打包后的虚幻引擎法式,需要有一个运行时的脚本系统,来实现一些定制化的逻辑,由于虚幻引擎的蓝图脚本系统不撑持运行时使用,因此可以选择 Lua、Python、TypeScript 等脚本语言实现相应的功能。
1、PuerTS 简介&插件安装

PuerTS 是游戏引擎下的 TypeScript 编程解决方案,它提供了一个 JavaScript 运行时,提供通过TypeScript访谒宿主引擎的能力[2]。Puerts 默认导入了所有反射 api,因此在 UE 蓝图里能调用的引擎 API,在 Typescript/JavaScript 环境都可以调用。有了这样一套可以在运行时使用的接口,便可以拿来在运行时编排逻辑。
要使用 PuerTS,首先创建一个 C++ 版本的 UE 工程。
PuerTS 的安装使用官方教程斗劲完善,工程中使用该插件,参照 puerts/install.md at master · Tencent/puerts · GitHub  链接中下载源码,注意下载完成后,仅拷贝该目录下的 Puerts 到虚幻引擎项目的 Plugins 中即可。


本工程测试时使用 Unreal 5.0.3 版本,因此又下载了一个适配的 V8 。在官方提供的链接中,跳转后下载编译好的版本。




下载完成解压后,将该目录下的 v8 文件夹整个拷贝到 YourProject/Plugins/Puerts/ThirdParty 目录下。完成后在 .uproject 上右键选择生成 sln 。


2、编写测试代码

2.1、编写 c++ 相关的代码

完成后在 YourProject.Build.cs 中添加相关的依赖模块:
  1. PrivateDependencyModuleNames.AddRange(new string[] { ”Puerts”, ”JsEnv” });
复制代码
添加完成后,在 GameMode.h 文件中添加一个执行脚本代码的函数。官方样例中给了一个在 BeginPlay 函数中生成 FJsEnv,然后执行对应脚本的例子。这里不想在一开始就执行脚本,想要在某个时机(例如按钮按下)执行所需的脚本。所以写了一个 ExecuteScript 函数,接受一个脚本文件,以及传来的一组参数。同时为了能够以调试模式执行脚本,增加了一个布尔参数。
此中,以调试模式执行脚本参考vscode_debug | PuerTS(普洱TS)[3]和 Puerts Inspector指南(一)在UE4和Unity里调试Javascript[4] 。
  1. // .h 文件
  2. public:
  3.         UFUNCTION(BlueprintCallable)
  4.         void ExecuteScript(FString ScriptPath, TMap<FString, UObject*> InArgs, bool bWithDebug);
  5.         TSharedPtr<puerts::FJsEnv> JsEnv;
  6. // .cpp 文件
  7. void ALearnPuerTSGameModeBase::ExecuteScript(FString ScriptPath, TMap<FString, UObject*> InArgs, bool bWithDebug)
  8. {
  9.         if (JsEnv)
  10.         {
  11.                 JsEnv.Reset();
  12.         }
  13.         if (bWithDebug)
  14.         {
  15.                 JsEnv = MakeShared<puerts::FJsEnv>(std::make_unique<puerts::DefaultJSModuleLoader>(TEXT(”JavaScript”)), std::make_shared<puerts::FDefaultLogger>(), 8080);
  16.                 JsEnv->WaitDebugger();
  17.         }
  18.         else
  19.         {
  20.                 JsEnv = MakeShared<puerts::FJsEnv>();
  21.         }
  22.         if (JsEnv)
  23.         {
  24.                 TArray<TPair<FString, UObject*>> RealArgs;
  25.                 for (const TPair<FString, UObject*>& Kvp : InArgs)
  26.                 {
  27.                         if (Kvp.Value != nullptr)
  28.                         {
  29.                                 const TPair<FString, UObject*> Item = TPair<FString, UObject*>(Kvp.Key, Kvp.Value);
  30.                                 RealArgs.Add(Item);
  31.                         }
  32.                 }
  33.                 FString ScriptBaseName = FPaths::GetBaseFilename(ScriptPath);
  34.                 JsEnv->Start(ScriptBaseName, RealArgs);
  35.         }
  36. }
复制代码
2.2、初始化编写脚本代码的环境

写完 C++ 相关的函数后,编译 sln 。然后发现并没有像官方提供的一个 Demo 那样有写 TS 代码的处所,搜索后发现需要做一些写 TS 代码初始化相关的操作[5][6]:
cmd 或 powershell 打开项目目录下: Plugins\Puerts ,并执行如下命令
node enable_puerts_module.js
该命令感化:
将 Puerts 下的 Content/Javascript 拷贝到 工程目录下的 Content 下
创建并初始化 tsconfig 文件 (内容来源于 enable_puerts_module.js 中 )
创建并初始化 DefaultPuerts.ini 到项目目录 Config 下(内容 AutoModeEnable=True )
在项目根目录创建 TypeScript 目录
npm 安装 Puerts_Editor 的依赖包
初始化相关操作的教程中提到去到工程根目录 cmd 或 powershell ,运行 npm init -y 创建一个默认的 package.json ,本项目只是学习使用 TS,不使用 ReactUMG,不必做这一步。
颠末以上操作后,YourProject 目录下会生成一个 TypeScript 目录,在里面新建一个 LearPuerTsQuickStart.ts 脚本文件,然后输入一些内容:
  1. import * as UE from &#39;ue&#39;
  2. import {$ref, $unref, $set, argv, on, toManualReleaseDelegate, releaseManualReleaseDelegate, blueprint} from &#39;puerts&#39;;
  3. let GameMode = argv.getByName(”GameMode”) as UE.LearnPuerTSGameModeBase;
  4. let MyWorld = GameMode.GetWorld();
  5. if(GameMode)
  6. {
  7.     UE.KismetSystemLibrary.PrintString(MyWorld,”脚本中获取到GameMode”,true,true,new UE.LinearColor(1.0,0.0,0.0,1.0),5.0,”None”);
  8. }
复制代码
2.3、UE Editor中的设置

完成后,打开 UE 编纂器,设置 World Setting 中的 GameMode 为我们写的 LeranPuerTsGameMode。
创建一个 UMG,此中创建两个按钮,分袂为


我们目前只使用执行脚本来测试我们写的脚本是否能被执行。在 UMG 中添加如下逻辑:


游戏一开始,获取到相应的 GameMode 对象,然后在”执行脚本”按钮后,将”ArgsPassToScript”变量添加一个
<”GameMode”, GameModeObject>这样一个键值对,传递给脚本代码使用。此中”ArgsPassToScript”是在 UMG 中创建的一个键为 FString,值为 UObject 的 Map。
然后在适当的位置创建该 UMG ,并AddtoViewPort。
运行起来法式后,点击执行脚本按钮,即可在左上角发现输出的内容,脚本被成功执行。


3、编纂器&打包后运行时更新脚本代码

执行脚本按钮和调试执行脚本按钮调用的 c++ 函数中先遏制掉了旧的虚拟机,然后新建了一个虚拟机读入 JavaScript 脚本,因此只要在脚本文件中写入新的代码逻辑,点击按钮即可看到新的逻辑生效。
  1. if (JsEnv)
  2. {
  3.         JsEnv.Reset();
  4. }
  5. if (bWithDebug)
  6. {
  7.         JsEnv = MakeShared<puerts::FJsEnv>(std::make_unique<puerts::DefaultJSModuleLoader>(TEXT(”JavaScript”)), std::make_shared<puerts::FDefaultLogger>(), 8080);
  8.         JsEnv->WaitDebugger();
  9. }
  10. else
  11. {
  12.         JsEnv = MakeShared<puerts::FJsEnv>();
  13. }
复制代码
4、编纂器&打包后运行时调试脚本代码

关于使用Puerts插件调试 JS 代码,Puerts Inspector指南(一)在UE4和Unity里调试Javascript 一文中有详细的图文指南和道理解释,参照文章中的教程即可,注意调试端口不要和其它法式冲突了。
参考


  • ^游戏引擎架构 第2版
  • ^普洱TS!Write your game with TypeScript in UE or Unity.  https://github.com/Tencent/puerts
  • ^自创建虚拟机的调试 https://puerts.github.io/docs/puerts/unreal/vscode_debug
  • ^Puerts Inspector指南(一)在UE4和Unity里调试Javascript https://zhuanlan.zhihu.com/p/359598262
  • ^跟我用TypeScript做一个FPS游戏 https://zhuanlan.zhihu.com/p/346531865
  • ^Puerts & ReactUMG 环境搭建(二) https://zhuanlan.zhihu.com/p/397369095

本帖子中包含更多资源

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

×
发表于 2023-8-15 15:49 | 显示全部楼层
厉害👍
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-4-28 02:18 , Processed in 0.272557 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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