允许游戏角色回合中复活
2023年11月21日 2024年1月11日
Respawn Component
说明
- 之前都是通过控制器复活游戏角色, 而控制器类型并不统一, 有PlayerController和AIController. 考虑到复用, 将回合中复活逻辑存放在组件
- 游戏角色死亡, 经过指定时间后, 允许复活. 但指定时间必须不大于游戏角色死亡时回合剩余时间; 游戏角色复活后, 拥有一定的时间行动
- RespawnTime 冷却时间 MinRoundActivityTime 回合中最小行动时间 - 之前文章结构尝试过从枝末攀附到衔接处, 或从框架延伸到枝叶. 本节先从RespawnComponent入手, 之后和GameModeBase的重建游戏角色逻辑搭上线, 最后再添加为PlayerController和AIController的组件
- 将RespawnComponent命名为RespawnColdComponent更合理一些
创建RespawnComponent
- | |
---|---|
基类 | ActorComponent |
路径 | Components |
名称 | STURespawnComponent |
属性 | Public |
整理RespawnComponent框架
- 构造函数中取消每秒更新
ShootThemUp: Components/STURespawnComponent.cpp
1PrimaryComponentTick.bCanEverTick = false;
- 屏蔽TickComponent的声明和定义
- 屏蔽BeginPlay的声明和定义
修改游戏规则
添加属性: 复活冷却时间
ShootThemUp: STUCoreTypes.h
1UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, meta = (ClampMin = "3", ClampMax = "20")) 2int32 RespawnTime = 5; // in seconds
实现RespawnComponent
添加属性: 定时器描述符 + 冷却计数
private
ShootThemUp: Components/STURespawnComponent.h
1// private 2int32 RespawnCountDown = 0; 3FTimerHandle RespawnTimer;
添加接口: 定时器回调函数
private
ShootThemUp: Components/STURespawnComponent.h
1void OnRespawnCountDown();
ShootThemUp: Components/STURespawnComponent.cpp
1#include "Engine/World.h" 2 3void USTURespawnComponent::OnRespawnCountDown() 4{ 5 if (!GetWorld()) return; 6 7 --RespawnCountDown; 8 9 if (!RespawnCountDown) 10 { 11 GetWorld()->GetTimerManager().ClearTimer(RespawnTimer); 12 SendRespawnRequest(); 13 } 14}
添加辅助接口: 调用GameMode复活接口
private
ShootThemUp: Components/STURespawnComponent.h
1void SendRespawnRequest();
ShootThemUp: Components/STURespawnComponent.cpp
1#include "STUGameModeBase.h" 2 3void USTURespawnComponent::SendRespawnRequest() 4{ 5 if (!GetWorld()) return; 6 7 const auto GameMode = Cast<ASTUGameModeBase>(GetWorld()->GetAuthGameMode()); 8 if (!GameMode) return; 9 10 GameMode->RespawnRequest(Cast<AController>(GetOwner())); 11}
添加接口: 开启定时器
public
ShootThemUp: Components/STURespawnComponent.h
1void RespawnCold(int32 RespawnTime);
和关卡中的计时器逻辑类似
ShootThemUp: Components/STURespawnComponent.cpp
1void USTURespawnComponent::RespawnCold(int32 RespawnTime) 2{ 3 if (!GetWorld()) return; 4 5 RespawnCountDown = RespawnTime; 6 GetWorld()->GetTimerManager().SetTimer(RespawnTimer, this, &USTURespawnComponent::OnRespawnCountDown, 1.0f, true); 7}
修改关卡逻辑
添加接口: 通过控制器复活游戏角色
public
ShootThemUp: STUGameModeBase.h
1void RespawnRequest(AController *Controller);
ShootThemUp: STUGameModeBase.cpp
1void ASTUGameModeBase::RespawnRequest(AController *Controller) 2{ 3 ResetOnePlayer(Controller); 4}
游戏角色死亡后进入复活冷却
private
ShootThemUp: STUGameModeBase.h
1void RespawnCold(AController *Controller);
ShootThemUp: STUGameModeBase.cpp
1#include "STUUtils.h" 2#include "Components/STURespawnComponent.h" 3 4void ASTUGameModeBase::RespawnCold(AController *Controller) 5{ 6 const auto RespawnAvailable = RoundCountDown > GameData.RespawnTime + MinRoundActivityTime; 7 if (!RespawnAvailable) return; 8 9 auto RespawnComponent = STUUtils::GetSTUPlayerComponent<USTURespawnComponent>(Controller); 10 if (!RespawnComponent) return; 11 12 RespawnComponent->RespawnCold(GameData.RespawnTime); 13}
死亡事件发生时调用
1// Killed 2RespawnCold(VictimController);
游戏角色复活后最小活动时间
- 可以存放在GameData中, 也可以存放在GameModeBase
- 没什么配置的必要
ShootThemUp: STUGameModeBase.h
1constexpr static int32 MinRoundActivityTime = 10;
当前流程梳理
- 游戏角色死亡后, ASTUGameModeBase::Killed被调用, 通过ASTUGameModeBase::RespawnCold进行冷却计时
- ASTUGameModeBase::RespawnCold调用控制器RespawnComponent的USTURespawnComponent::RespawnCold, 开启定时器
- 定时器每秒触发, 当计数器为0时, 调用ASTUGameModeBase::RespawnRequest尝试复活游戏角色
为AIController添加RespawnComponent
protected
ShootThemUp: AI/STUAIController.h
1class USTURespawnComponent; 2 3UPROPERTY(VisibleAnywhere, BlueprintReadWrite) 4USTURespawnComponent *STURespawnComponent;
ShootThemUp: AI/STUAIController.cpp
1#include "Components/STURespawnComponent.h" 2 3// 构造函数 4STURespawnComponent = CreateDefaultSubobject<USTURespawnComponent>("STURespawnComponent");
为PlayerController添加RespawnComponent
添加组件
protected
ShootThemUp: Player/STUPlayerController.h
1class USTURespawnComponent; 2 3UPROPERTY(VisibleAnywhere, BlueprintReadWrite) 4USTURespawnComponent *STURespawnComponent;
添加构造函数
public
ShootThemUp: Player/STUPlayerController.h
1ASTUPlayerController();
初始化组件
ShootThemUp: Player/STUPlayerController.cpp
1#include "Components/STURespawnComponent.h" 2 3ASTUPlayerController::ASTUPlayerController() 4{ 5 STURespawnComponent = CreateDefaultSubobject<USTURespawnComponent>("STURespawnComponent"); 6}
查看
- | 单位(s) |
---|---|
当前回合时长 | 30 |
回合最小活动时间 | 10 |
复活冷却 | 5 |
- NPC死亡后可以复活
- 死亡时, 回合剩余时间大于15s时, 可以复活
- 死亡时, 回合剩余时间小于15s时, 在下一回合复活