UE4中使用Lua替换蓝图

UE4 中的蓝图

UE4 的蓝图其实是个很不错的工具,可视化开发游戏逻辑,降低非程序人员的使用门槛,可热更新,但最大的问题是不能合并,并且当逻辑复杂之后会变得难以理解,项目越大这些问题越突出。所以大家都各显神通,推出自己的脚本框架来替换蓝图,如 sluaunrealUnreal.jsunreal.lua

Bluelua

Github: Bluelua 这个插件是基于我之前使用蓝图做项目的经验造的另一个轮子,目标就是用 lua 替换蓝图的逻辑,但是保持和蓝图一致的使用习惯,和蓝图用来继承 C++ 类编写游戏逻辑一样,同样用 lua 来继承 C++ 类来编写游戏逻辑,支持重载 BlueprintImplementableEventBlueprintNativeEvent 方法,基于 UE4 反射系统,可直接访问 UPROPERTY 属性,直接调用 BlueprintCallable 方法,而不用生成胶水代码。

详细的使用方式见项目主页,目前是打算将官方一个示例 Github: LuaActionRPG 改成 lua 实现,到现在已经将界面和 PlayerCharacter 相关的蓝图逻辑移到 lua 中了,还没完全移完,在转移的过程中也是逐渐完善这个插件,顺便测试各个特性,目前这个插件已经是处于可用的状态了

Bluelua 和蓝图对比

ActionRPG 示例中 PlayerController 的 Tick 部分的逻辑在蓝图中是这样一大堆

蓝图的Tick函数
蓝图的Tick函数

替换成 lua 代码后的逻辑是这样的 PlayerController.lua

function m:ReceiveTick(DeltaSeconds)
    local GameMode = GameplayStatics:GetGameMode(Super)
    local ControlledPawn = Super:K2_GetPawn()
    if GameMode.bAutoBattleMode or not ControlledPawn or Super.bBlockedMovement then
        return
    end

    if ControlledPawn.Mesh:GetAnimInstance():IsAnyMontagePlaying() then
        local MovingVector = KismetMathLibrary:MakeVector(Super:GetInputAxisValue('MoveForward'), Super:GetInputAxisValue('MoveRight'), 0)

        if KismetMathLibrary:VSize(MovingVector) > 0 then
            local CameraRotation = Super.PlayerCameraManager:GetCameraRotation()
            local NewRotation = KismetMathLibrary:NormalizedDeltaRotator(
                KismetMathLibrary:MakeRotFromX(MovingVector), KismetMathLibrary:MakeRotator(0, 0, CameraRotation.Yaw - 1))
            ControlledPawn:K2_SetActorRotation(NewRotation, false)
        end
    else
        local CameraRotation = Super.PlayerCameraManager:GetCameraRotation()

        ControlledPawn:AddMovementInput(KismetMathLibrary:GetForwardVector(CameraRotation), Super:GetInputAxisValue('MoveForward'), false)
        ControlledPawn:AddMovementInput(KismetMathLibrary:GetRightVector(CameraRotation), Super:GetInputAxisValue('MoveRight'), false)
    end
end

可以看出,用 lua 来写逻辑更加简洁明了

最后,欢迎大家 star, fork, pr,反馈使用过程中的 bug 和建议, Have fun!