实现游戏角色跑步
2023年6月11日 2024年1月11日
概览
跑步条件
- 按下Shift键
- 运动方向为向前
- 判断方法1:同时按下
W
或Up
- 判断方法2:速度矢量和朝向的夹角为0
- 判断方法1:同时按下
- 速度不为0
前方有障碍物时,游戏角色无法跑步
跑步时,播放跑步动画
跑步时,游戏角色运动速度提高
绑定跑步键位
虚幻编辑器
项目设置 > Engine > Input
动作映射
函数描述 | 键位 |
---|---|
Run | LeftShift |
实现跑步逻辑
C++
- | 回调函数签名 |
---|---|
BindAction | void handler() |
函数描述 | 回调函数 | |
---|---|---|
Run | RunEnable | 按下时触发 |
RunDisable | 松开时触发 |
搭建框架
- 添加空函数
ShootThemUp: Player/STUBaseCharacter.cpp
1void ASTUBaseCharacter::RunEnable() {} 2void ASTUBaseCharacter::RunDisable() {}
- 绑定函数描述和回调函数
ShootThemUp: Player/STUBaseCharacter.cpp
1// SetupPlayerInputComponent 2PlayerInputComponent->BindAction("Run", IE_Pressed, this, &ASTUBaseCharacter::RunEnable); 3PlayerInputComponent->BindAction("Run", IE_Released, this, &ASTUBaseCharacter::RunDisable);
- 添加函数声明
private
ShootThemUp: Player/STUBaseCharacter.h
实现回调函数
键位生效时,设置标识位
- 定义标志位
private
ShootThemUp: Player/STUBaseCharacter.h
1bool AbleRun = false;
- 键位事件发生时, 更新标志位
ShootThemUp: Player/STUBaseCharacter.cpp
1void ASTUBaseCharacter::RunEnable() 2{ 3 AbleRun = true; 4} 5void ASTUBaseCharacter::RunDisable() 6{ 7 AbleRun = false; 8}
运动方向向前时,设置标志位
- 定义标志位
private
ShootThemUp: Player/STUBaseCharacter.h
1bool IsForward = false;
- MoveForward被调用时, 更新标志位
ShootThemUp: Player/STUBaseCharacter.cpp
1// MoveForward 2IsForward = Amount > 0.0f;
添加接口, 返回跑步条件满足情况
- 添加函数声明
public
可在蓝图中调用,也可供其他类使用
ShootThemUp: Player/STUBaseCharacter.h
1UFUNCTION(BlueprintCallable) 2bool IsRunning() const;
- 实现
ShootThemUp: Player/STUBaseCharacter.cpp
1bool ASTUBaseCharacter::IsRunning() const 2{ 3 return AbleRun && IsForward && !GetVelocity().IsZero(); 4}
添加跑步动画
虚幻编辑器
创建混合空间资产作为跑步动画
Blend Space 1D
- 创建 Content/Player/Animations/BS_Locomotion_Run,绑定骨骼网格体 HeroTPP_Skeleton
- 设置轴
Asset Details > Axis Settings > Horizontal Axis
- Name Velocity Maximum Axis Value 600 - 设置动画
- 起点 Idle 终点 RoadieRun_Fwd
在动画蓝图中引入跑步动画
ABP_BaseCharacter
状态机说明
- 新增状态: Run
- 状态迁移
- Walk > Run 满足跑步条件 Run > Walk 不再满足跑步条件 Run > JumpStart 游戏角色在空中
使状态机管理跑步状态
- 添加布尔型变量IsRunning
-
设置变量IsRunning
EventGraph
-
使用
STUBaseCharacter::IsRunning
,需要Pawn
到STUBaseCharacter
的转换 -
设置IsFalling后, 执行Pawn到STUBaseCharacter的转换
-
转换完成后, 设置变量
IsRunning
-
完整
EventGraph
-
可以合并
Pawn
到Character
和STUBaseCharacter
的转换
-
-
状态机中添加跑步状态
AnimGraph
-
将BS_Locomotion_Run拖入到状态机, 命令为
Run
-
双击
Run
,设置BS_Locomotion_Run输入
-
-
添加状态迁移条件
- 触发条件 Walk > Run 满足跑步条件 STUBaseCharacter::IsRunning 返回true Run > Walk 不再满足跑步条件 STUBaseCharacter::IsRunning 返回false Run > JumpStart 游戏角色在空中 复用 Walk > JumpStart 迁移条件 -
Walk <> Run
-
状态迁移路径
-
Walk > Run
迁移条件 -
Run > Walk
迁移条件
-
-
Run > Jump
-
状态迁移路径
-
初稿
-
优解
- 如果
IsRunning
为true
, 发生JumpEnd > Walk
时, 会立即从Walk
切换到Run
- 省略
JumpEnd > =Run
,可以降低状态机复杂度
- 如果
-
-
复用迁移条件
Run > JumpStart
复用Walk > JumpStart
迁移条件-
选中 Walk > JumpStart 迁移条件, Details > Transiton > Transition Rule Sharing > Promote To Share
-
命名为
IsFalling
,共享条件显示为红色 -
选中 Run > JumpStart 迁移条件, Details > Transition > Transition Rule Sharing > Use Shared > 选择IsFalling
-
完整状态机
-
-
-
效果
运行游戏,走路到跑步动画正常切换
实现跑步加速
创建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
- 屏蔽默认构造函数声明,声明构造函数
ShootThemUp: Player/STUBaseCharacter.h
1// ASTUBaseCharacter(); 2ASTUBaseCharacter(const FObjectInitializer &ObjInit);
- 修改构造函数初始化列表
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}