Puerts项目:Unreal引擎与TypeScript交互调用指南
概述
在Unreal引擎开发中,Puerts项目为开发者提供了强大的引擎与TypeScript交互能力。本文将深入讲解如何在Unreal引擎(或纯C++代码)中调用TypeScript脚本的各种方法,帮助开发者实现高效的跨语言通信。
核心交互方式
1. 使用DYNAMIC_DELEGATE实现双向通信
DYNAMIC_DELEGATE是Unreal引擎提供的一种委托机制,Puerts通过它实现了C++与TypeScript的高效交互。
1.1 UClass中的DYNAMIC_DELEGATE字段
C++端定义示例:
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FNotifyWithInt, int32, A);
DECLARE_DYNAMIC_DELEGATE_RetVal_OneParam(FString, FNotifyWithStringRet, FString, A);
UCLASS()
class PUERTS_UNREAL_DEMO_API AMyActor : public AActor
{
GENERATED_BODY()
UPROPERTY()
FNotifyWithInt NotifyWithInt;
UPROPERTY()
FNotifyWithStringRet NotifyWithStringRet;
};
TypeScript绑定示例:
// 多播委托绑定
actor.NotifyWithInt.Add((i) => console.log("收到整数:", i));
// 带返回值的委托绑定
actor.NotifyWithStringRet.Bind((str) => {
return "处理后的字符串: " + str;
});
C++触发调用:
// 广播多播委托
NotifyWithInt.Broadcast(123);
// 调用带返回值的委托
FString Result = NotifyWithStringRet.Execute("输入字符串");
1.2 非UClass成员的DYNAMIC_DELEGATE
对于普通C++类中的委托,Puerts提供了多种绑定方式:
方式一:自动释放绑定
import {toDelegate} from 'puerts';
function Handler(str: string): boolean {
return str === "特定值";
}
// owner释放时自动释放绑定
obj.PassJsFunctionAsDelegate(toDelegate(owner, Handler));
方式二:手动释放绑定
import {toManualReleaseDelegate, releaseManualReleaseDelegate} from 'puerts';
const handler = toManualReleaseDelegate((str) => str === "特定值");
obj.PassJsFunctionAsDelegate(handler);
// 使用完毕后需要手动释放
releaseManualReleaseDelegate(handler);
方式三:绑定到UFunction
import {toDelegate} from 'puerts';
// 绑定到UObject的UFunction
obj.PassJsFunctionAsDelegate(toDelegate(obj, "HandlerFunction"));
2. 使用std::function实现纯C++交互
对于非Unreal特定的C++代码,推荐使用标准库的std::function:
C++端定义:
void StdFunctionTest(std::function<int(int, int)> Func) {
int Result = Func(10, 20);
// 使用结果...
}
TypeScript调用:
obj.StdFunctionTest((x, y) => {
console.log(`收到参数: ${x}, ${y}`);
return x * y; // 返回乘积
});
蓝图与TypeScript交互
1. 静态脚本方法
通过继承BlueprintFunctionLibrary,可以创建蓝图可调用的静态方法:
import * as UE from "ue";
class TsUtils extends UE.BlueprintFunctionLibrary {
public static CalculateDamage(base: number, multiplier: number): number {
return base * multiplier;
}
}
export default TsUtils;
在蓝图中,这些方法会像普通蓝图函数一样显示和使用。
2. 成员脚本方法
通过继承UE类并实现特定方法,可以在蓝图中调用TypeScript实现的成员方法:
class MyActor extends UE.Actor {
Tick(deltaTime: number): void {
// 每帧逻辑
}
}
3. Mixin模式增强
Mixin提供了一种灵活的扩展方式,无需继承即可增强现有类:
UE.Mixin(SomeActor, {
ReceiveBeginPlay() {
// 重写ReceiveBeginPlay逻辑
},
CustomMethod() {
// 添加新方法
}
});
最佳实践建议
-
委托选择:优先使用DYNAMIC_DELEGATE与Unreal引擎深度集成,纯C++模块考虑std::function
-
内存管理:注意委托绑定的生命周期,避免内存泄漏
-
性能考量:频繁调用的接口应考虑性能影响,必要时进行优化
-
类型安全:确保TypeScript与C++间的类型转换正确,特别是复杂类型
-
调试技巧:充分利用console.log输出调试信息,结合Unreal日志系统进行问题追踪
通过合理运用这些交互方式,开发者可以在Unreal项目中充分发挥TypeScript的灵活性,同时保持引擎原生性能,实现高效的游戏开发工作流。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考