|
在游戏引擎语境中,脚本语言是高级、相对容易使用的编程语言,可供用户便利地使用引擎经常用到的功能。借助于脚本语言,法式的开发者和使用者能够便利的定制一个现存的游戏。
对比更改原生法式代码,需要从头编译及链接法式,脚本语言主要有以下优势:直译、轻量、撑持快速迭代、便利易用。[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 中添加相关的依赖模块:- PrivateDependencyModuleNames.AddRange(new string[] { ”Puerts”, ”JsEnv” });
复制代码 添加完成后,在 GameMode.h 文件中添加一个执行脚本代码的函数。官方样例中给了一个在 BeginPlay 函数中生成 FJsEnv,然后执行对应脚本的例子。这里不想在一开始就执行脚本,想要在某个时机(例如按钮按下)执行所需的脚本。所以写了一个 ExecuteScript 函数,接受一个脚本文件,以及传来的一组参数。同时为了能够以调试模式执行脚本,增加了一个布尔参数。
此中,以调试模式执行脚本参考vscode_debug | PuerTS(普洱TS)[3]和 Puerts Inspector指南(一)在UE4和Unity里调试Javascript[4] 。- // .h 文件
- public:
- UFUNCTION(BlueprintCallable)
- void ExecuteScript(FString ScriptPath, TMap<FString, UObject*> InArgs, bool bWithDebug);
- TSharedPtr<puerts::FJsEnv> JsEnv;
- // .cpp 文件
- void ALearnPuerTSGameModeBase::ExecuteScript(FString ScriptPath, TMap<FString, UObject*> InArgs, bool bWithDebug)
- {
- if (JsEnv)
- {
- JsEnv.Reset();
- }
- if (bWithDebug)
- {
- JsEnv = MakeShared<puerts::FJsEnv>(std::make_unique<puerts::DefaultJSModuleLoader>(TEXT(”JavaScript”)), std::make_shared<puerts::FDefaultLogger>(), 8080);
- JsEnv->WaitDebugger();
- }
- else
- {
- JsEnv = MakeShared<puerts::FJsEnv>();
- }
- if (JsEnv)
- {
- TArray<TPair<FString, UObject*>> RealArgs;
- for (const TPair<FString, UObject*>& Kvp : InArgs)
- {
- if (Kvp.Value != nullptr)
- {
- const TPair<FString, UObject*> Item = TPair<FString, UObject*>(Kvp.Key, Kvp.Value);
- RealArgs.Add(Item);
- }
- }
- FString ScriptBaseName = FPaths::GetBaseFilename(ScriptPath);
- JsEnv->Start(ScriptBaseName, RealArgs);
- }
- }
复制代码 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 脚本文件,然后输入一些内容:- import * as UE from 'ue'
- import {$ref, $unref, $set, argv, on, toManualReleaseDelegate, releaseManualReleaseDelegate, blueprint} from 'puerts';
- let GameMode = argv.getByName(”GameMode”) as UE.LearnPuerTSGameModeBase;
- let MyWorld = GameMode.GetWorld();
- if(GameMode)
- {
- UE.KismetSystemLibrary.PrintString(MyWorld,”脚本中获取到GameMode”,true,true,new UE.LinearColor(1.0,0.0,0.0,1.0),5.0,”None”);
- }
复制代码 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 脚本,因此只要在脚本文件中写入新的代码逻辑,点击按钮即可看到新的逻辑生效。- if (JsEnv)
- {
- JsEnv.Reset();
- }
- if (bWithDebug)
- {
- JsEnv = MakeShared<puerts::FJsEnv>(std::make_unique<puerts::DefaultJSModuleLoader>(TEXT(”JavaScript”)), std::make_shared<puerts::FDefaultLogger>(), 8080);
- JsEnv->WaitDebugger();
- }
- else
- {
- JsEnv = MakeShared<puerts::FJsEnv>();
- }
复制代码 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
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|