Added Gameplay Abilities(Health, MaxHealth, Mana, MaxMana)

This commit is contained in:
Caleb Buhungiro
2025-06-17 22:30:27 +08:00
parent 9a6a072b5a
commit 6d8fc727d2
14 changed files with 234 additions and 12 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -17,6 +17,10 @@
"TargetAllowList": [ "TargetAllowList": [
"Editor" "Editor"
] ]
},
{
"Name": "GameplayAbilities",
"Enabled": true
} }
] ]
} }

View File

@@ -7,17 +7,26 @@ public class Crunch : ModuleRules
public Crunch(ReadOnlyTargetRules Target) : base(Target) public Crunch(ReadOnlyTargetRules Target) : base(Target)
{ {
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput" });
PrivateDependencyModuleNames.AddRange(new string[] { }); PublicDependencyModuleNames.AddRange([
"Core",
"CoreUObject",
"Engine",
"InputCore",
"EnhancedInput",
"GameplayAbilities",
"GameplayTasks",
"GameplayTags"
]);
PrivateDependencyModuleNames.AddRange(new string[] { });
// Uncomment if you are using Slate UI // Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features // Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem"); // PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
} }
} }

View File

@@ -3,18 +3,33 @@
#include "Crunch/Public/Character/CCharacter.h" #include "Crunch/Public/Character/CCharacter.h"
#include "GAS/CAbilitySystemComponent.h"
#include "GAS/CAttributeSet.h"
// Sets default values
ACCharacter::ACCharacter() ACCharacter::ACCharacter()
{ {
PrimaryActorTick.bCanEverTick = true; PrimaryActorTick.bCanEverTick = true;
GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision); GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
CAbilitySystemComponent = CreateDefaultSubobject<UCAbilitySystemComponent>(TEXT("Ability System Component"));
CAttributeSet = CreateDefaultSubobject<UCAttributeSet>(TEXT("CAttribute Set"));
}
void ACCharacter::ServerSideInit()
{
CAbilitySystemComponent->InitAbilityActorInfo(this, this);
CAbilitySystemComponent->ApplyInitialEffects();
}
void ACCharacter::ClientSideInit()
{
CAbilitySystemComponent->InitAbilityActorInfo(this, this);
} }
void ACCharacter::BeginPlay() void ACCharacter::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
} }
void ACCharacter::Tick(float DeltaTime) void ACCharacter::Tick(float DeltaTime)
@@ -27,3 +42,8 @@ void ACCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponen
Super::SetupPlayerInputComponent(PlayerInputComponent); Super::SetupPlayerInputComponent(PlayerInputComponent);
} }
UAbilitySystemComponent* ACCharacter::GetAbilitySystemComponent() const
{
return CAbilitySystemComponent;
}

View File

@@ -0,0 +1,16 @@
// Multiplayer By Caleb
#include "GAS/CAbilitySystemComponent.h"
void UCAbilitySystemComponent::ApplyInitialEffects()
{
if (!GetOwner() || !GetOwner()->HasAuthority()) return;
for (const auto& EffectClass : InitialEffects)
{
auto GameplayEffectSpecHandle{MakeOutgoingSpec(EffectClass, 1, MakeEffectContext())};
ApplyGameplayEffectSpecToSelf(*GameplayEffectSpecHandle.Data.Get());
}
}

View File

@@ -0,0 +1,34 @@
// Multiplayer By Caleb
#include "GAS/CAttributeSet.h"
#include "Net/UnrealNetwork.h"
void UCAttributeSet::GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, Health, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, Mana, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, MaxMana, COND_None, REPNOTIFY_Always);
}
void UCAttributeSet::OnRep_Health(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCAttributeSet, Health, OldValue);
}
void UCAttributeSet::OnRep_MaxHealth(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCAttributeSet, MaxHealth, OldValue);
}
void UCAttributeSet::OnRep_Mana(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCAttributeSet, Mana, OldValue);
}
void UCAttributeSet::OnRep_MaxMana(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCAttributeSet, MaxMana, OldValue);
}

View File

@@ -3,3 +3,24 @@
#include "Crunch/Public/Player/CPlayerController.h" #include "Crunch/Public/Player/CPlayerController.h"
#include "Character/CPlayerCharacter.h"
void ACPlayerController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
CPlayerCharacter = Cast<ACPlayerCharacter>(InPawn);
if (CPlayerCharacter)
{
CPlayerCharacter->ServerSideInit();
}
}
void ACPlayerController::AcknowledgePossession(class APawn* P)
{
Super::AcknowledgePossession(P);
CPlayerCharacter = Cast<ACPlayerCharacter>(P);
if (CPlayerCharacter)
{
CPlayerCharacter->ClientSideInit();
}
}

View File

@@ -3,16 +3,19 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "AbilitySystemInterface.h"
#include "GameFramework/Character.h" #include "GameFramework/Character.h"
#include "CCharacter.generated.h" #include "CCharacter.generated.h"
UCLASS() UCLASS()
class CRUNCH_API ACCharacter : public ACharacter class CRUNCH_API ACCharacter : public ACharacter, public IAbilitySystemInterface
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
ACCharacter(); ACCharacter();
void ServerSideInit();
void ClientSideInit();
protected: protected:
virtual void BeginPlay() override; virtual void BeginPlay() override;
@@ -21,4 +24,14 @@ public:
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
/********************************************************************************************/
/* Gameplay Ability */
/********************************************************************************************/
public:
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
private:
UPROPERTY(EditDefaultsOnly, Category="Gameplay Effects")
class UCAbilitySystemComponent* CAbilitySystemComponent;
UPROPERTY()
class UCAttributeSet* CAttributeSet;
}; };

View File

@@ -0,0 +1,21 @@
// Multiplayer By Caleb
#pragma once
#include "CoreMinimal.h"
#include "AbilitySystemComponent.h"
#include "CAbilitySystemComponent.generated.h"
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class CRUNCH_API UCAbilitySystemComponent : public UAbilitySystemComponent
{
GENERATED_BODY()
public:
void ApplyInitialEffects();
private:
UPROPERTY(EditDefaultsOnly, Category="Gameplay Effects")
TArray<TSubclassOf<UGameplayEffect>> InitialEffects;
};

View File

@@ -0,0 +1,68 @@
// Multiplayer By Caleb
#pragma once
#include "CoreMinimal.h"
#include "AbilitySystemComponent.h"
#include "AttributeSet.h"
#include "CAttributeSet.generated.h"
/**
* This defines a set of helper functions for accessing and initializing attributes, to avoid having to manually write these functions.
* It would creates the following functions, for attribute Health
*
* static FGameplayAttribute UMyHealthSet::GetHealthAttribute();
* FORCEINLINE float UMyHealthSet::GetHealth() const;
* FORCEINLINE void UMyHealthSet::SetHealth(float NewVal);
* FORCEINLINE void UMyHealthSet::InitHealth(float NewVal);
*
* To use this in your game you can define something like this, and then add game-specific functions as necessary:
*
* #define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
* GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
* GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
* GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
* GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
*
* ATTRIBUTE_ACCESSORS(UMyHealthSet, Health)
*/
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
UCLASS()
class CRUNCH_API UCAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
ATTRIBUTE_ACCESSORS(UCAttributeSet, Health);
ATTRIBUTE_ACCESSORS(UCAttributeSet, MaxHealth);
ATTRIBUTE_ACCESSORS(UCAttributeSet, Mana);
ATTRIBUTE_ACCESSORS(UCAttributeSet, MaxMana);
virtual void GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const override;
private:
UPROPERTY(ReplicatedUsing=OnRep_Health)
FGameplayAttributeData Health;
UPROPERTY(ReplicatedUsing=OnRep_MaxHealth)
FGameplayAttributeData MaxHealth;
UPROPERTY(ReplicatedUsing=OnRep_Mana)
FGameplayAttributeData Mana;
UPROPERTY(ReplicatedUsing=OnRep_MaxMana)
FGameplayAttributeData MaxMana;
UFUNCTION()
void OnRep_Health(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_MaxHealth(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_Mana(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_MaxMana(const FGameplayAttributeData& OldValue);
};

View File

@@ -13,4 +13,14 @@ UCLASS()
class CRUNCH_API ACPlayerController : public APlayerController class CRUNCH_API ACPlayerController : public APlayerController
{ {
GENERATED_BODY() GENERATED_BODY()
public:
// Only called on the server
virtual void OnPossess(APawn* InPawn) override;
// Only called on the client, also on the listening server
virtual void AcknowledgePossession(class APawn* P) override;
private:
UPROPERTY()
class ACPlayerCharacter* CPlayerCharacter;
}; };