feat: Binaries添加到LFS,增加生命值网络同步功能

This commit is contained in:
2025-12-05 13:26:37 +08:00
parent 6f7b761234
commit 5187e3c0a2
33 changed files with 254 additions and 60 deletions

View File

@@ -0,0 +1 @@
html/*

View File

@@ -14,7 +14,7 @@ class UDamageableInterface : public UInterface {
/**
* @class IDamageableInterface
* @brief 伤害组件
* @brief 伤害接口
* @ingroup Battle
*/
class FIRSTPERSONDEMO_API IDamageableInterface {

View File

@@ -2,28 +2,41 @@
#include "Surviver_FPS/Battle/EnemyBase.h"
#include "HealthComponent.h"
#include "GameFramework/Actor.h"
// Sets default values
/**
* @brief AEnemyBase的构造函数。
*/
AEnemyBase::AEnemyBase() {
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
// 允许该Pawn每帧调用Tick()
PrimaryActorTick.bCanEverTick = true;
// 创建并附加生命组件
HealthComponent = CreateDefaultSubobject<UHealthComponent>(TEXT("HealthComponent"));
}
// Called when the game starts or when spawned
void AEnemyBase::BeginPlay() {
Super::BeginPlay();
}
// Called every frame
void AEnemyBase::Tick(float DeltaTime) {
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void AEnemyBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
/**
* @brief 接收伤害的实现。
* @param DamageAmount 伤害量。
* @param InstigatorActor 造成伤害的Actor。
*/
void AEnemyBase::ReceiveDamage(float DamageAmount, AActor* InstigatorActor) {
return;
if (HealthComponent)
{
// 通过生命组件处理伤害
HealthComponent->HandleDamage(DamageAmount);
}
}

View File

@@ -7,36 +7,41 @@
#include "GameFramework/Pawn.h"
#include "EnemyBase.generated.h"
class UHealthComponent;
/**
* @class AEnemyBase
* @brief 敌人基类
* @brief 敌人基类,实现了可受伤害接口。
* @ingroup Battle
* @todo 实现TakeDamage接口挂HealthComponent组件
*/
UCLASS()
class FIRSTPERSONDEMO_API AEnemyBase : public APawn, public IDamageableInterface {
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
/**
* @brief 构造函数设置Pawn的默认属性。
*/
AEnemyBase();
protected:
// Called when the game starts or when spawned
/**
* @brief 管理敌人生命值的组件。
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UHealthComponent* HealthComponent;
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
/**
* @brief 敌人受伤函数
* @param DamageAmount 伤害量
* @brief 接收伤害的接口实现。
* @param DamageAmount 伤害量
* @param InstigatorActor 造成伤害的Actor。
*/
virtual void ReceiveDamage(float DamageAmount, AActor* InstigatorActor) override;
};

View File

@@ -2,36 +2,66 @@
#include "HealthComponent.h"
#include "GameFramework/Actor.h"
#include "Net/UnrealNetwork.h"
#include "Kismet/GameplayStatics.h"
/**
* @brief 定义需要网络同步的属性。
* @param OutLifetimeProps 存储同步属性的数组。
*/
void UHealthComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const {
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
// Sets default values for this component's properties
UHealthComponent::UHealthComponent() {
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// ...
DOREPLIFETIME(UHealthComponent, CurrentHealth);
}
/**
* @brief UHealthComponent的构造函数。
*/
UHealthComponent::UHealthComponent() {
// 关闭每帧Tick以提高性能
PrimaryComponentTick.bCanEverTick = false;
// 默认启用网络复制
SetIsReplicatedByDefault(true);
}
// Called when the game starts
/**
* @brief 组件开始运行时调用。
*/
void UHealthComponent::BeginPlay() {
Super::BeginPlay();
// 初始化当前生命值为最大生命值
CurrentHealth = MaxHealth;
}
// ...
/**
* @brief 当CurrentHealth属性被复制时在客户端上调用。
*/
void UHealthComponent::OnRep_CurrentHealth() {
// 在客户端上当CurrentHealth被复制时调用
}
// Called every frame
void UHealthComponent::TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction) {
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// ...
}
/**
* @brief 供外部调用的伤害处理函数。
* @param DamageAmount 伤害量。
*/
void UHealthComponent::HandleDamage(float DamageAmount) {
if (DamageAmount <= 0.0f) {
return;
}
// 仅在服务器上处理伤害逻辑
if (GetOwner()->HasAuthority()) {
CurrentHealth = FMath::Clamp(CurrentHealth - DamageAmount, 0.0f, MaxHealth);
if (CurrentHealth <= 0.0f) {
OnDeath.Broadcast();
}
}
}

View File

@@ -4,8 +4,14 @@
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Net/UnrealNetwork.h"
#include "HealthComponent.generated.h"
/**
* @brief 当生命值降为0时调用的多播委托。
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDeath);
/**
* @class UHealthComponent
* @brief 生命组件
@@ -17,30 +23,46 @@ class FIRSTPERSONDEMO_API UHealthComponent : public UActorComponent {
GENERATED_BODY()
public:
// Sets default values for this component's properties
UHealthComponent();
/**
* @brief 死亡时广播的多播委托。可以在蓝图中绑定事件。
*/
UPROPERTY(BlueprintAssignable, Category = "Health")
FOnDeath OnDeath;
protected:
// 最大生命值
/**
* @brief 角色的最大生命值。
*/
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Health")
float MaxHealth = 100.0f;
// 当前生命值
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category="Health")
/**
* @brief 角色的当前生命值。此属性会从服务器复制到客户端。
*/
UPROPERTY(BlueprintReadOnly, ReplicatedUsing=OnRep_CurrentHealth, Category="Health")
float CurrentHealth;
// Called when the game starts
virtual void BeginPlay() override;
/**
* @brief 当CurrentHealth属性被复制时在客户端上调用的函数。
* @todo 处理客户端上的血条UI更新等逻辑。
*/
UFUNCTION()
void OnRep_CurrentHealth();
/**
* @brief 游戏开始时调用,用于初始化组件。
*/
virtual void BeginPlay() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction) override;
/**
* @brief 处理伤害
* @param DamageAmount 伤害量
* @todo 实现血量计算,处理死亡逻辑
* @brief 外部调用以处理伤害的函数。
* @param DamageAmount 伤害量
*/
UFUNCTION(BlueprintCallable, Category="Health")
void HandleDamage(float DamageAmount);

View File

@@ -2,30 +2,62 @@
#include "SuriverPlayer.h"
#include "HealthComponent.h"
#include "GameFramework/Actor.h"
// Sets default values
/**
* @brief ASuriverPlayer的构造函数。
*/
ASuriverPlayer::ASuriverPlayer() {
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
// 允许该角色每帧调用Tick()
PrimaryActorTick.bCanEverTick = true;
// 创建并附加生命组件
HealthComponent = CreateDefaultSubobject<UHealthComponent>(TEXT("HealthComponent"));
}
// Called when the game starts or when spawned
/**
* @brief 游戏开始或角色生成时调用。
*/
void ASuriverPlayer::BeginPlay() {
Super::BeginPlay();
if (HealthComponent) {
HealthComponent->OnDeath.AddDynamic(this, &ASuriverPlayer::OnPlayerDied);
}
}
// Called every frame
/**
* @brief 每帧调用。
* @param DeltaTime 帧间隔时间。
*/
void ASuriverPlayer::Tick(float DeltaTime) {
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
/**
* @brief 绑定输入功能。
* @param PlayerInputComponent 用于绑定输入的组件。
*/
void ASuriverPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
/**
* @brief 接收伤害的实现。
* @param DamageAmount 伤害量。
* @param InstigatorActor 造成伤害的Actor。
*/
void ASuriverPlayer::ReceiveDamage(float DamageAmount, AActor* InstigatorActor) {
if (HealthComponent) {
// 通过生命组件处理伤害
HealthComponent->HandleDamage(DamageAmount);
}
}
/**
* @brief 当玩家死亡时调用,打印日志。
* @todo 通知 GameMode 玩家已死亡,处理结算逻辑
*/
void ASuriverPlayer::OnPlayerDied() {
UE_LOG(LogTemp, Warning, TEXT("你死了"));
}

View File

@@ -7,31 +7,48 @@
#include "GameFramework/Character.h"
#include "SuriverPlayer.generated.h"
class UHealthComponent;
/**
* @class ASuriverPlayer
* @brief 玩家基类
* @brief 玩家角色基类,实现了可受伤害接口。
* @ingroup Battle
* @todo 实现TakeDamage接口挂HealthComponent组件
*/
UCLASS()
class FIRSTPERSONDEMO_API ASuriverPlayer : public ACharacter, public IDamageableInterface {
GENERATED_BODY()
public:
// Sets default values for this character's properties
/**
* @brief 构造函数,设置角色的默认属性。
*/
ASuriverPlayer();
protected:
// Called when the game starts or when spawned
/**
* @brief 管理角色生命值的组件。
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
UHealthComponent* HealthComponent;
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
/**
* @brief 当玩家死亡时调用。
* @todo 添加死亡处理逻辑如UI弹窗等
*/
UFUNCTION()
void OnPlayerDied();
// Called to bind functionality to input
public:
virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
/**
* @brief 接收伤害的接口实现。
* @param DamageAmount 伤害量。
* @param InstigatorActor 造成伤害的Actor。
*/
virtual void ReceiveDamage(float DamageAmount, AActor* InstigatorActor) override;
};

View File

@@ -2,12 +2,12 @@
/**
* @defgroup GameCore 核心玩法系统
* 包含游戏模式、角色和控制器等基础类。
* 包含游戏模式、控制器等基础类。
*/
/**
* @defgroup Battle 战斗系统
* 包含所有枪械、投射物和拾取物。
* 包含玩家角色、敌人、枪械、投射物和拾取物。
*/
/**