六一的部落格


关关难过关关过,前路漫漫亦灿灿。




概览


跑步条件

  1. 按下Shift键
  2. 运动方向为向前
    • 判断方法1:同时按下 WUp
    • 判断方法2:速度矢量和朝向的夹角为0
  3. 速度不为0

    前方有障碍物时,游戏角色无法跑步

跑步时,播放跑步动画


跑步时,游戏角色运动速度提高


绑定跑步键位

虚幻编辑器

项目设置 > Engine > Input

动作映射

函数描述 键位
Run LeftShift



实现跑步逻辑

C++

- 回调函数签名
BindAction void handler()
函数描述 回调函数
Run RunEnable 按下时触发
RunDisable 松开时触发

搭建框架

  1. 添加空函数

    ShootThemUp: Player/STUBaseCharacter.cpp
    1void ASTUBaseCharacter::RunEnable() {}
    2void ASTUBaseCharacter::RunDisable() {}
  2. 绑定函数描述和回调函数

    ShootThemUp: Player/STUBaseCharacter.cpp
    1// SetupPlayerInputComponent
    2PlayerInputComponent->BindAction("Run", IE_Pressed, this, &ASTUBaseCharacter::RunEnable);
    3PlayerInputComponent->BindAction("Run", IE_Released, this, &ASTUBaseCharacter::RunDisable);
  3. 添加函数声明

    private

    ShootThemUp: Player/STUBaseCharacter.h

实现回调函数


键位生效时,设置标识位

  1. 定义标志位

    private

    ShootThemUp: Player/STUBaseCharacter.h
    1bool AbleRun = false;
  2. 键位事件发生时, 更新标志位

    ShootThemUp: Player/STUBaseCharacter.cpp
    1void ASTUBaseCharacter::RunEnable()
    2{
    3    AbleRun = true;
    4}
    5void ASTUBaseCharacter::RunDisable()
    6{
    7    AbleRun = false;
    8}

运动方向向前时,设置标志位

  1. 定义标志位

    private

    ShootThemUp: Player/STUBaseCharacter.h
    1bool IsForward = false;
  2. MoveForward被调用时, 更新标志位

    ShootThemUp: Player/STUBaseCharacter.cpp
    1// MoveForward
    2IsForward = Amount > 0.0f;

添加接口, 返回跑步条件满足情况

  1. 添加函数声明

    public

    可在蓝图中调用,也可供其他类使用

    ShootThemUp: Player/STUBaseCharacter.h
    1UFUNCTION(BlueprintCallable)
    2bool IsRunning() const;
  2. 实现

    ShootThemUp: Player/STUBaseCharacter.cpp
    1bool ASTUBaseCharacter::IsRunning() const
    2{
    3    return AbleRun && IsForward && !GetVelocity().IsZero();
    4}

添加跑步动画

虚幻编辑器


创建混合空间资产作为跑步动画

Blend Space 1D

  1. 创建 Content/Player/Animations/BS_Locomotion_Run,绑定骨骼网格体 HeroTPP_Skeleton
  2. 设置轴

    Asset Details > Axis Settings > Horizontal Axis
    -
    Name Velocity
    Maximum Axis Value 600
  3. 设置动画
    -
    起点 Idle
    终点 RoadieRun_Fwd

在动画蓝图中引入跑步动画

ABP_BaseCharacter


状态机说明

  • 新增状态: Run
  • 状态迁移
    -
    Walk > Run 满足跑步条件
    Run > Walk 不再满足跑步条件
    Run > JumpStart 游戏角色在空中

使状态机管理跑步状态

  • 添加布尔型变量IsRunning
  • 设置变量IsRunning

    EventGraph

    1. 使用 STUBaseCharacter::IsRunning ,需要 PawnSTUBaseCharacter 的转换


    2. 设置IsFalling后, 执行Pawn到STUBaseCharacter的转换

    3. 转换完成后, 设置变量 IsRunning


    4. 完整 EventGraph


    5. 可以合并 PawnCharacterSTUBaseCharacter 的转换

  • 状态机中添加跑步状态

    AnimGraph

    1. 将BS_Locomotion_Run拖入到状态机, 命令为 Run


    2. 双击 Run ,设置BS_Locomotion_Run输入


  • 添加状态迁移条件

    - 触发条件
    Walk > Run 满足跑步条件 STUBaseCharacter::IsRunning 返回true
    Run > Walk 不再满足跑步条件 STUBaseCharacter::IsRunning 返回false
    Run > JumpStart 游戏角色在空中 复用 Walk > JumpStart 迁移条件
    • Walk <> Run

      1. 状态迁移路径


      2. Walk > Run 迁移条件


      3. Run > Walk 迁移条件


    • Run > Jump

      • 状态迁移路径

        1. 初稿


        2. 优解


          • 如果 IsRunningtrue, 发生 JumpEnd > Walk 时, 会立即从 Walk 切换到 Run
          • 省略 JumpEnd > =Run ,可以降低状态机复杂度
      • 复用迁移条件

        Run > JumpStart 复用 Walk > JumpStart 迁移条件

        1. 选中 Walk > JumpStart 迁移条件, Details > Transiton > Transition Rule Sharing > Promote To Share


        2. 命名为 IsFalling ,共享条件显示为红色



        3. 选中 Run > JumpStart 迁移条件, Details > Transition > Transition Rule Sharing > Use Shared > 选择IsFalling


        4. 完整状态机



效果

运行游戏,走路到跑步动画正常切换


实现跑步加速


创建Components/CharacterMovementComponent的派生类

虚幻编辑器

  • CharacterMovementComponent


  • 公有类



设置头文件搜索路径

ShootThemUp: ShootThemUp.Build.cs

1PublicIncludePaths.AddRange(new string[] { "ShootThemUp/Public/Player", "ShootThemUp/Public/Components" });         

满足跑步条件时, 增加游戏角色运动速度上限

C++


添加加速系数

protected

ShootThemUp: Components/STUCharacterMovementComponent.h

1UPROPERTY(EditDefaultsOnly, meta = (ClampMin = "1.5", ClampMax = "10.0"))
2float SpeedAcceleration = 2.0f;

覆写UCharacterMovementComponent::GetMaxSpeed

  • 并不直接修改 MaxWalkSpeed
  • 某个地方会调用 GetMaxSpeed 来确定 Character 运动速度的上限,当获取的 MaxWalkSpeed 增加,速度增加的幅度也变大,用以实现加速
  • 添加函数声明

    public

    ShootThemUp: Components/STUCharacterMovementComponent.h

    1virtual float GetMaxSpeed() const override;
  • 实现

    ShootThemUp: Components/STUCharacterMovementComponent.cpp

    1#include "Player/STUBaseCharacter.h"
    2
    3float USTUCharacterMovementComponent::GetMaxSpeed() const
    4{
    5    const float MaxSpeed = Super::GetMaxSpeed();
    6    ASTUBaseCharacter *Player = Cast<ASTUBaseCharacter>(GetPawnOwner());
    7    return Player && Player->IsRunning() ? SpeedAcceleration * MaxSpeed : MaxSpeed;
    8}

游戏角色使用STUCharacterMovementComponent

  1. 屏蔽默认构造函数声明,声明构造函数

    ShootThemUp: Player/STUBaseCharacter.h
    1// ASTUBaseCharacter();
    2ASTUBaseCharacter(const FObjectInitializer &ObjInit);
  2. 修改构造函数初始化列表

    ShootThemUp: Player/STUBaseCharacter.cpp
    1#include "Components/STUCharacterMovementComponent.h"
    2
    3ASTUBaseCharacter::ASTUBaseCharacter(const FObjectInitializer &ObjInit)
    4    : Super(ObjInit.SetDefaultSubobjectClass<USTUCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
    5{
    6    // ...
    7}

实现游戏角色跑步



概览


跑步条件

  1. 按下Shift键
  2. 运动方向为向前
    • 判断方法1:同时按下 WUp
    • 判断方法2:速度矢量和朝向的夹角为0
  3. 速度不为0

    前方有障碍物时,游戏角色无法跑步

跑步时,播放跑步动画


跑步时,游戏角色运动速度提高


绑定跑步键位

虚幻编辑器

项目设置 > Engine > Input

动作映射

函数描述 键位
Run LeftShift



实现跑步逻辑

C++

- 回调函数签名
BindAction void handler()
函数描述 回调函数
Run RunEnable 按下时触发
RunDisable 松开时触发

搭建框架

  1. 添加空函数

    ShootThemUp: Player/STUBaseCharacter.cpp
    1void ASTUBaseCharacter::RunEnable() {}
    2void ASTUBaseCharacter::RunDisable() {}
  2. 绑定函数描述和回调函数

    ShootThemUp: Player/STUBaseCharacter.cpp
    1// SetupPlayerInputComponent
    2PlayerInputComponent->BindAction("Run", IE_Pressed, this, &ASTUBaseCharacter::RunEnable);
    3PlayerInputComponent->BindAction("Run", IE_Released, this, &ASTUBaseCharacter::RunDisable);
  3. 添加函数声明

    private

    ShootThemUp: Player/STUBaseCharacter.h

实现回调函数


键位生效时,设置标识位

  1. 定义标志位

    private

    ShootThemUp: Player/STUBaseCharacter.h
    1bool AbleRun = false;
  2. 键位事件发生时, 更新标志位

    ShootThemUp: Player/STUBaseCharacter.cpp
    1void ASTUBaseCharacter::RunEnable()
    2{
    3    AbleRun = true;
    4}
    5void ASTUBaseCharacter::RunDisable()
    6{
    7    AbleRun = false;
    8}

运动方向向前时,设置标志位

  1. 定义标志位

    private

    ShootThemUp: Player/STUBaseCharacter.h
    1bool IsForward = false;
  2. MoveForward被调用时, 更新标志位

    ShootThemUp: Player/STUBaseCharacter.cpp
    1// MoveForward
    2IsForward = Amount > 0.0f;

添加接口, 返回跑步条件满足情况

  1. 添加函数声明

    public

    可在蓝图中调用,也可供其他类使用

    ShootThemUp: Player/STUBaseCharacter.h
    1UFUNCTION(BlueprintCallable)
    2bool IsRunning() const;
  2. 实现

    ShootThemUp: Player/STUBaseCharacter.cpp
    1bool ASTUBaseCharacter::IsRunning() const
    2{
    3    return AbleRun && IsForward && !GetVelocity().IsZero();
    4}

添加跑步动画

虚幻编辑器


创建混合空间资产作为跑步动画

Blend Space 1D

  1. 创建 Content/Player/Animations/BS_Locomotion_Run,绑定骨骼网格体 HeroTPP_Skeleton
  2. 设置轴

    Asset Details > Axis Settings > Horizontal Axis
    -
    Name Velocity
    Maximum Axis Value 600
  3. 设置动画
    -
    起点 Idle
    终点 RoadieRun_Fwd

在动画蓝图中引入跑步动画

ABP_BaseCharacter


状态机说明

  • 新增状态: Run
  • 状态迁移
    -
    Walk > Run 满足跑步条件
    Run > Walk 不再满足跑步条件
    Run > JumpStart 游戏角色在空中

使状态机管理跑步状态

  • 添加布尔型变量IsRunning
  • 设置变量IsRunning

    EventGraph

    1. 使用 STUBaseCharacter::IsRunning ,需要 PawnSTUBaseCharacter 的转换


    2. 设置IsFalling后, 执行Pawn到STUBaseCharacter的转换

    3. 转换完成后, 设置变量 IsRunning


    4. 完整 EventGraph


    5. 可以合并 PawnCharacterSTUBaseCharacter 的转换

  • 状态机中添加跑步状态

    AnimGraph

    1. 将BS_Locomotion_Run拖入到状态机, 命令为 Run


    2. 双击 Run ,设置BS_Locomotion_Run输入


  • 添加状态迁移条件

    - 触发条件
    Walk > Run 满足跑步条件 STUBaseCharacter::IsRunning 返回true
    Run > Walk 不再满足跑步条件 STUBaseCharacter::IsRunning 返回false
    Run > JumpStart 游戏角色在空中 复用 Walk > JumpStart 迁移条件
    • Walk <> Run

      1. 状态迁移路径


      2. Walk > Run 迁移条件


      3. Run > Walk 迁移条件


    • Run > Jump

      • 状态迁移路径

        1. 初稿


        2. 优解


          • 如果 IsRunningtrue, 发生 JumpEnd > Walk 时, 会立即从 Walk 切换到 Run
          • 省略 JumpEnd > =Run ,可以降低状态机复杂度
      • 复用迁移条件

        Run > JumpStart 复用 Walk > JumpStart 迁移条件

        1. 选中 Walk > JumpStart 迁移条件, Details > Transiton > Transition Rule Sharing > Promote To Share


        2. 命名为 IsFalling ,共享条件显示为红色



        3. 选中 Run > JumpStart 迁移条件, Details > Transition > Transition Rule Sharing > Use Shared > 选择IsFalling


        4. 完整状态机



效果

运行游戏,走路到跑步动画正常切换


实现跑步加速


创建Components/CharacterMovementComponent的派生类

虚幻编辑器

  • CharacterMovementComponent


  • 公有类



设置头文件搜索路径

ShootThemUp: ShootThemUp.Build.cs

1PublicIncludePaths.AddRange(new string[] { "ShootThemUp/Public/Player", "ShootThemUp/Public/Components" });         

满足跑步条件时, 增加游戏角色运动速度上限

C++


添加加速系数

protected

ShootThemUp: Components/STUCharacterMovementComponent.h

1UPROPERTY(EditDefaultsOnly, meta = (ClampMin = "1.5", ClampMax = "10.0"))
2float SpeedAcceleration = 2.0f;

覆写UCharacterMovementComponent::GetMaxSpeed

  • 并不直接修改 MaxWalkSpeed
  • 某个地方会调用 GetMaxSpeed 来确定 Character 运动速度的上限,当获取的 MaxWalkSpeed 增加,速度增加的幅度也变大,用以实现加速
  • 添加函数声明

    public

    ShootThemUp: Components/STUCharacterMovementComponent.h

    1virtual float GetMaxSpeed() const override;
  • 实现

    ShootThemUp: Components/STUCharacterMovementComponent.cpp

    1#include "Player/STUBaseCharacter.h"
    2
    3float USTUCharacterMovementComponent::GetMaxSpeed() const
    4{
    5    const float MaxSpeed = Super::GetMaxSpeed();
    6    ASTUBaseCharacter *Player = Cast<ASTUBaseCharacter>(GetPawnOwner());
    7    return Player && Player->IsRunning() ? SpeedAcceleration * MaxSpeed : MaxSpeed;
    8}

游戏角色使用STUCharacterMovementComponent

  1. 屏蔽默认构造函数声明,声明构造函数

    ShootThemUp: Player/STUBaseCharacter.h
    1// ASTUBaseCharacter();
    2ASTUBaseCharacter(const FObjectInitializer &ObjInit);
  2. 修改构造函数初始化列表

    ShootThemUp: Player/STUBaseCharacter.cpp
    1#include "Components/STUCharacterMovementComponent.h"
    2
    3ASTUBaseCharacter::ASTUBaseCharacter(const FObjectInitializer &ObjInit)
    4    : Super(ObjInit.SetDefaultSubobjectClass<USTUCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
    5{
    6    // ...
    7}