Tencent/puerts项目中的蓝图Mixin技术详解

Tencent/puerts项目中的蓝图Mixin技术详解

puerts PUER(普洱) Typescript. Let's write your game in UE or Unity with TypeScript. puerts 项目地址: https://gitcode.com/gh_mirrors/pu/puerts

什么是蓝图Mixin

在Unreal Engine开发中,蓝图Mixin是一种强大的技术,它允许开发者将TypeScript类混合到现有的蓝图类中。通过Tencent/puerts项目提供的这一功能,开发者可以在保持原有蓝图结构的同时,用TypeScript代码增强或修改蓝图类的行为。

核心特性

1. 函数覆盖与增强

  • 当TypeScript类与蓝图类拥有同名函数时,TypeScript逻辑会自动替换蓝图逻辑
  • 支持覆盖Unreal Engine原生事件(如ReceiveBeginPlay等)
  • 可以添加蓝图类中不存在的新方法和字段

2. 类型安全

  • 系统会自动检查TypeScript函数与蓝图函数的兼容性
  • 遵循TypeScript的协变逆变规则,确保类型安全

3. 性能优化

  • TypeScript可以直接调用蓝图方法,并享有完整的代码提示
  • 底层实现高效,不会引入不必要的性能开销

基础使用教程

1. 加载目标蓝图类

首先需要加载你想要混合的蓝图类:

let ucls = UE.Class.Load('/Game/StarterContent/MixinTest.MixinTest_C');
const MixinTest = blueprint.tojs<typeof UE.Game.StarterContent.MixinTest.MixinTest_C>(ucls);

2. 创建TypeScript混合类

定义一个TypeScript类来实现你想要混合的功能:

interface Loggable extends UE.Game.StarterContent.MixinTest.MixinTest_C {};

class Loggable {
    // 覆盖蓝图中的同名函数
    Log(msg: string): void {
        console.log(this.GetName(), msg);
        console.log(`1 + 3 = ${this.TsAdd(1, 3)}`);
    }

    // 新增TypeScript特有方法
    TsAdd(x: number, y: number): number {
        console.log(`Ts Add(${x}, ${y})`)
        return x + y;
    }
}

3. 执行混合操作

使用blueprint.mixin方法将TypeScript类混合到蓝图类中:

const MixinTestWithMixin = blueprint.mixin(MixinTest, Loggable);

4. 使用混合后的类

现在可以像使用普通蓝图类一样使用混合后的类:

world.SpawnActor(MixinTestWithMixin.StaticClass(), undefined, UE.ESpawnActorCollisionHandlingMethod.Undefined, undefined, undefined) as Loggable;

高级应用场景

1. 对象生命周期管理

puerts提供了两种对象生命周期管理方式:

方式一:TypeScript持有UE对象(默认)

  • TypeScript stub对象持有UE对象的强引用
  • 当TypeScript对象不再被引用时,UE对象也会被释放

方式二:UE持有TypeScript对象

  • UE对象持有TypeScript stub对象的强引用
  • 当UE对象被销毁时,TypeScript对象也会被释放

可以通过blueprint.mixin的第三个参数配置:

blueprint.mixin(MixinTest, Loggable, { objectTakeByNative: true });

2. 继承与super调用

当需要调用被覆盖的父类方法时,需要特殊处理:

// 创建中转类
interface MixinSuperTestBasePlaceHold extends UE.Game.StarterContent.MixinSuperTestBase.MixinSuperTestBase_C {};
class MixinSuperTestBasePlaceHold {}
Object.setPrototypeOf(MixinSuperTestBasePlaceHold.prototype, MixinSuperTestBase.prototype);

// 继承中转类
class DerivedClassMixin extends MixinSuperTestBasePlaceHold {
    Foo(): void {
        console.log("i am ts mixin");
        super.Foo();  // 现在可以正确调用父类方法
    }
}

3. 原生C++类的混合

puerts支持对C++原生类的BlueprintNativeEvent和BlueprintImplementableEvent方法进行混合:

class Calc {
    Mult(x: number, y: number): number {
        console.log(`Ts Mult(${x}, ${y})`)
        return x * y;
    }

    Div(x: number, y: number): number {
        console.log(`Ts Div(${x}, ${y})`)
        return x / y;
    }
}

interface Calc extends UE.MainObject {};
blueprint.mixin(UE.MainObject, Calc);

注意事项

  1. 事件覆盖:确保被混合的蓝图类中已经定义了你要覆盖的事件(即使逻辑为空),否则在子类中可能无法正确调用TypeScript逻辑。

  2. 新增字段:新增字段实际上是存储在TypeScript stub对象中:

    • objectTakeByNative为false时,需要保持对stub对象的引用
    • objectTakeByNative为true时,确保UE对象被引擎正确持有
  3. 性能考虑:虽然混合操作本身高效,但频繁的跨语言调用仍可能影响性能,建议将相关逻辑尽量集中处理。

通过Tencent/puerts的蓝图Mixin功能,开发者可以灵活地在TypeScript和蓝图之间架起桥梁,充分发挥两种开发方式的优势,提升开发效率和代码质量。

puerts PUER(普洱) Typescript. Let's write your game in UE or Unity with TypeScript. puerts 项目地址: https://gitcode.com/gh_mirrors/pu/puerts

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

屈蒙吟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值