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

1
.gitattributes vendored
View File

@@ -1 +1,2 @@
Content/** filter=lfs diff=lfs merge=lfs -text
Binaries/** filter=lfs diff=lfs merge=lfs -text

4
.gitignore vendored
View File

@@ -1,4 +1,4 @@
Binaries
# Binaries
DerivedDataCache
Intermediate
Saved
@@ -9,9 +9,11 @@ Saved
*.opendb
*.sdf
*.sln
*.sln.DotSettings.user
*.suo
*.xcodeproj
*.xcworkspace
.idea
.vsconfig
*.pdb

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,3 +1,11 @@
# FirstPersonDemo
Developed with Unreal Engine 5
asdfasdf
sdfsdfdsf
dsfsdfd
sdds
Ciallo

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 战斗系统
* 包含所有枪械、投射物和拾取物。
* 包含玩家角色、敌人、枪械、投射物和拾取物。
*/
/**