添加游戏角色死亡逻辑
2023年6月11日 2024年1月19日
说明
- 生命值修改时, 同步到HealthTextComponent组件
- 生命值为0,销毁游戏角色
- 死亡时, 播放死亡动画
动画剪辑
Animation Montage
- 可以将多个动画组合播放。把希望连续播放的动画添加到时间线
timeline
,在代码或蓝图中播放动画剪辑 - 命名:以AM_打头
Slot
若此时播放动画剪辑,输出输入动画和动画剪辑的拼接;若无动画剪辑在播放,输出输入动画
添加委托:当生命值更改时,同步到HealthTextComponent文本
C++
屏蔽当前HealthTextComponent文本的设置
ShootThemUp: Player/STUBaseCharacter.cpp
屏蔽Tick函数中的文本更新
初始化HealthTextComponent文本
ShootThemUp: Player/STUBaseCharacter.cpp
1// BeginPlay 2HealthTextComponent->SetText(FText::FromString(FString::Printf(TEXT("%.0f"), HealthComponent->GetHealth())));
HealthComponent提供委托服务: 生命值修改通知
- |
---|
多播 |
仅C++ |
在HealthComponent定义委托类型FChangeHealthSignature
ShootThemUp: Components/STUHealthComponent.h
1DECLARE_MULTICAST_DELEGATE(FChangeHealthSignature);
添加数据成员OnChangeHealth,提供委托服务
public
ShootThemUp: Components/STUHealthComponent.h
1FChangeHealthSignature OnChangeHealth;
封装修改Health逻辑,调用时通知客户端
只能通过SetHealth接口修改生命值
- 函数定义
ShootThemUp: Components/STUHealthComponent.cpp
1void USTUHealthComponent::SetHealth(float NewHealth) 2{ 3 Health = NewHealth; 4 OnChangeHealth.Broadcast(); 5}
- 函数声明
private
ShootThemUp: Components/STUHealthComponent.h
修改OnTakeAnyDamage
ShootThemUp: Components/STUHealthComponent.cpp
1// Health -= Damage; 2SetHealth(Health - Damage);
STUBaseCharacter注册委托服务: OnChangeHealth
- | |
---|---|
仅C++ | AddUObject |
搭建框架: 注册生命值修改通知
- 添加空函数
ShootThemUp: Player/STUBaseCharacter.cpp
1void ASTUBaseCharacter::OnChangeHealth() {}
- 注册委托服务
ShootThemUp: Player/STUBaseCharacter.cpp
1// BeginPlay 2HealthComponent->OnChangeHealth.AddUObject(this, &ASTUBaseCharacter::OnChangeHealth);
- 函数声明
private
ShootThemUp: Player/STUBaseCharacter.h
实现处理函数OnChangeHealth
设置HealthTextComponent文本
ShootThemUp: Player/STUBaseCharacter.cpp
1// OnChangeHealth 2HealthTextComponent->SetText(FText::FromString(FString::Printf(TEXT("%.0f"), HealthComponent->GetHealth())));
Character和其组件调用BeginPlay的先后顺序
先调用Component的BeginPlay,再调用Character的BeginPlay。
先由HealthComponent在BeginPlay初始化Health, 才轮到Character在BeginPlay中注册服务。
若我们没有在Character的BeginPlay中初始化HealthTextComponent文本,当Character在BeginPlay中注册服务完成,HealthTextComponent 文本显示为0。直到Health再次被更改,Character才会收到通知同步。
游戏角色死亡后,生命值不再减少
C++
提供接口,判断Character是否死亡
public
ShootThemUp: Components/STUHealthComponent.h
1UFUNCTION(BlueprintCallable) 2bool IsDead() const { return Health <= 0.0f; }
Character死亡之后,生命值不再减少
若伤害的数量特征不大于0,或者当前生命值不大于0,无法继续对Character造成伤害
ShootThemUp: Components/STUHealthComponent.cpp
1// OnTakeAnyDamage 2if (Damage <= 0.0f || IsDead()) return;
限制Health范围
ShootThemUp: Components/STUHealthComponent.cpp
1// Health = NewHealth; 2Health = FMath::Clamp(NewHealth, 0.0f, MaxHealth);
添加委托:游戏角色死亡,销毁Character
C++
当生命值发生改变时修改HealthText文本,当生命值变为0时销毁Character,一码归一码
HealthComponent提供委托服务: 游戏角色死亡通知
- |
---|
多播 |
仅C++ |
在HealthComponent定义委托类型FDeathSignature
ShootThemUp: Components/STUHealthComponent.h
1DECLARE_MULTICAST_DELEGATE(FDeathSignature);
添加数据成员OnDeath,提供委托服务
public
ShootThemUp: Components/STUHealthComponent.h
1FDeathSignature OnDeath;
Character死亡,通知客户端
ShootThemUp: Components/STUHealthComponent.cpp
1// OnTakeAnyDamage 2if (IsDead()) 3{ 4 OnDeath.Broadcast(); 5}
STUBaseCharacter注册委托服务: OnDeath
- | |
---|---|
仅C++ | AddUObject |
搭建框架: 注册死亡通知
- 添加空函数
ShootThemUp: Player/STUBaseCharacter.cpp
1void ASTUBaseCharacter::OnDeath() {}
- 注册委托服务
ShootThemUp: Player/STUBaseCharacter.cpp
1// BeginPlay 2HealthComponent->OnDeath.AddUObject(this, &ASTUBaseCharacter::OnDeath);
- 函数声明
private
ShootThemUp: Player/STUBaseCharacter.h
实现处理函数OnDeath
- 添加销毁延时
protected
ShootThemUp: Player/STUBaseCharacter.h
1UPROPERTY(EditDefaultsOnly, meta = (ClampMin = "0.0", ClampMax = "10.0")) 2float LifeSpanOnDeath = 5.0f;
- 检查CharacterMovement组件有效性
ShootThemUp: Player/STUBaseCharacter.cpp
1// BeginPlay 2check(GetCharacterMovement());
- 剥夺玩家对游戏角色的控制权,开启定时器销毁Character
ShootThemUp: Player/STUBaseCharacter.cpp
1// OnDeath 2GetCharacterMovement()->DisableMovement(); 3SetLifeSpan(LifeSpanOnDeath);
创建死亡动画剪辑
虚幻编辑器
之前的跳跃、跑步、转向动画,均对应状态机中的一个状态。如果游戏角色死亡拥有对应状态,每个状态都可能迁移到死亡状态,光是想想都觉得麻烦
使用动画剪辑 AnimMontage
资产,当游戏角色死亡时,播放死亡动画剪辑, 通过slot连接当前动画和死亡动画剪辑
创建AnimMontage资产
- | |
---|---|
死亡动画资产 | ExternalContent/Animation/Animations/TTP_Animations/Death |
-
选中死亡动画资产,右键 > Create > Create AnimMontage > 命名为AM_Death
-
移动到Content/Player/Animations路径下
在动画蓝图中添加Slot
ABP_BaseCharacter > AnimGraph
在Locomotion和OutputPose之间添加Slot
Slot和AM_Death的分组一致
-
Slot
- SlotName DefaultGroup.DefaultSlot
-
AM_Death
- Montage DefaultGroup.DefaultSlot
设置动画剪辑
AM_Death
死亡动画结束后,不再播放其他动画
Asset Details > BlendOptions > EnableAutoBlendOut,取消勾选
游戏角色死亡时,播放动画剪辑
C++
C++类型 | |
---|---|
动画剪辑 AnimMontage |
UAnimMontage |
添加UAnimMontage类型数据成员
protected
ShootThemUp: Player/STUBaseCharacter.h
1UPROPERTY(EditDefaultsOnly) 2UAnimMontage *DeathAnimMontage;
Character死亡时,播放动画剪辑
ShootThemUp: Player/STUBaseCharacter.cpp
1// OnDeath 2PlayAnimMontage(DeathAnimMontage);
查看
虚幻编辑器
-
设置游戏角色死亡时播放的动画剪辑
BP_STUBaseCharacter
-
效果图
禁止移动Character之后,销毁Character之前,仍可以移动Camera;即,水平旋转视角时可以旋转Character