From 6d8fc727d277407cd091826603b4ab0b13a684a7 Mon Sep 17 00:00:00 2001 From: Caleb Buhungiro Date: Tue, 17 Jun 2025 22:30:27 +0800 Subject: [PATCH] Added Gameplay Abilities(Health, MaxHealth, Mana, MaxMana) --- .../Crunch/Animation/AnimBP_Crunch.uasset | 4 +- .../GameplayEffect/GE_Init.uasset | 3 + .../GameplayEffects/GE_FullStat.uasset | 3 + Content/Player/CPlayerCharacter_BP.uasset | 4 +- Crunch.uproject | 4 ++ Source/Crunch/Crunch.Build.cs | 19 ++++-- .../Crunch/Private/Character/CCharacter.cpp | 24 ++++++- .../Private/GAS/CAbilitySystemComponent.cpp | 16 +++++ Source/Crunch/Private/GAS/CAttributeSet.cpp | 34 ++++++++++ .../Private/Player/CPlayerController.cpp | 21 ++++++ Source/Crunch/Public/Character/CCharacter.h | 15 +++- .../Public/GAS/CAbilitySystemComponent.h | 21 ++++++ Source/Crunch/Public/GAS/CAttributeSet.h | 68 +++++++++++++++++++ .../Crunch/Public/Player/CPlayerController.h | 10 +++ 14 files changed, 234 insertions(+), 12 deletions(-) create mode 100644 Content/Characters/Crunch/GameplayAbility/GameplayEffect/GE_Init.uasset create mode 100644 Content/GameplayAbilities/GameplayEffects/GE_FullStat.uasset create mode 100644 Source/Crunch/Private/GAS/CAbilitySystemComponent.cpp create mode 100644 Source/Crunch/Private/GAS/CAttributeSet.cpp create mode 100644 Source/Crunch/Public/GAS/CAbilitySystemComponent.h create mode 100644 Source/Crunch/Public/GAS/CAttributeSet.h diff --git a/Content/Characters/Crunch/Animation/AnimBP_Crunch.uasset b/Content/Characters/Crunch/Animation/AnimBP_Crunch.uasset index 828bfd1..df3d258 100644 --- a/Content/Characters/Crunch/Animation/AnimBP_Crunch.uasset +++ b/Content/Characters/Crunch/Animation/AnimBP_Crunch.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:92b9d78c73f4c306502907fac5bb07fd9071a7905d96d575ddce374704fd2431 -size 360747 +oid sha256:b7c0c093f7d19b4d2f07fce17e77c20789774d279ba056a6c199e07b16e521a0 +size 360965 diff --git a/Content/Characters/Crunch/GameplayAbility/GameplayEffect/GE_Init.uasset b/Content/Characters/Crunch/GameplayAbility/GameplayEffect/GE_Init.uasset new file mode 100644 index 0000000..477270b --- /dev/null +++ b/Content/Characters/Crunch/GameplayAbility/GameplayEffect/GE_Init.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e519cebf375b205d0485d8c9813ed0dea1fec9a833da2fe9aba18d494f8846e +size 17527 diff --git a/Content/GameplayAbilities/GameplayEffects/GE_FullStat.uasset b/Content/GameplayAbilities/GameplayEffects/GE_FullStat.uasset new file mode 100644 index 0000000..9a37519 --- /dev/null +++ b/Content/GameplayAbilities/GameplayEffects/GE_FullStat.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:632c99abfc7476d9bb308c2afd5cbab686fd79d9e97ddf8c70b6a2ee701401ee +size 17667 diff --git a/Content/Player/CPlayerCharacter_BP.uasset b/Content/Player/CPlayerCharacter_BP.uasset index 59ff755..5d91fd7 100644 --- a/Content/Player/CPlayerCharacter_BP.uasset +++ b/Content/Player/CPlayerCharacter_BP.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d86dcb4b90a4bfda804fa48efab992506d6647d84c39d2ed47240bc663a54176 -size 38812 +oid sha256:ee1f1a8e0b363af824fdccb2b03f46f7924a51065b714e749a3977c94adcf859 +size 39859 diff --git a/Crunch.uproject b/Crunch.uproject index 157ebfb..1eebc4e 100644 --- a/Crunch.uproject +++ b/Crunch.uproject @@ -17,6 +17,10 @@ "TargetAllowList": [ "Editor" ] + }, + { + "Name": "GameplayAbilities", + "Enabled": true } ] } \ No newline at end of file diff --git a/Source/Crunch/Crunch.Build.cs b/Source/Crunch/Crunch.Build.cs index 5e11c13..863b651 100644 --- a/Source/Crunch/Crunch.Build.cs +++ b/Source/Crunch/Crunch.Build.cs @@ -7,17 +7,26 @@ public class Crunch : ModuleRules public Crunch(ReadOnlyTargetRules Target) : base(Target) { 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 // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); - + // Uncomment if you are using online features // PrivateDependencyModuleNames.Add("OnlineSubsystem"); // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true } -} +} \ No newline at end of file diff --git a/Source/Crunch/Private/Character/CCharacter.cpp b/Source/Crunch/Private/Character/CCharacter.cpp index 0a47bd0..e613d8c 100644 --- a/Source/Crunch/Private/Character/CCharacter.cpp +++ b/Source/Crunch/Private/Character/CCharacter.cpp @@ -3,18 +3,33 @@ #include "Crunch/Public/Character/CCharacter.h" +#include "GAS/CAbilitySystemComponent.h" +#include "GAS/CAttributeSet.h" + -// Sets default values ACCharacter::ACCharacter() { PrimaryActorTick.bCanEverTick = true; GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision); + + CAbilitySystemComponent = CreateDefaultSubobject(TEXT("Ability System Component")); + CAttributeSet = CreateDefaultSubobject(TEXT("CAttribute Set")); +} + +void ACCharacter::ServerSideInit() +{ + CAbilitySystemComponent->InitAbilityActorInfo(this, this); + CAbilitySystemComponent->ApplyInitialEffects(); +} + +void ACCharacter::ClientSideInit() +{ + CAbilitySystemComponent->InitAbilityActorInfo(this, this); } void ACCharacter::BeginPlay() { Super::BeginPlay(); - } void ACCharacter::Tick(float DeltaTime) @@ -27,3 +42,8 @@ void ACCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponen Super::SetupPlayerInputComponent(PlayerInputComponent); } +UAbilitySystemComponent* ACCharacter::GetAbilitySystemComponent() const +{ + return CAbilitySystemComponent; +} + diff --git a/Source/Crunch/Private/GAS/CAbilitySystemComponent.cpp b/Source/Crunch/Private/GAS/CAbilitySystemComponent.cpp new file mode 100644 index 0000000..2f7378c --- /dev/null +++ b/Source/Crunch/Private/GAS/CAbilitySystemComponent.cpp @@ -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()); + } +} diff --git a/Source/Crunch/Private/GAS/CAttributeSet.cpp b/Source/Crunch/Private/GAS/CAttributeSet.cpp new file mode 100644 index 0000000..3607cc6 --- /dev/null +++ b/Source/Crunch/Private/GAS/CAttributeSet.cpp @@ -0,0 +1,34 @@ +// Multiplayer By Caleb + + +#include "GAS/CAttributeSet.h" + +#include "Net/UnrealNetwork.h" + +void UCAttributeSet::GetLifetimeReplicatedProps(TArray& 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); +} diff --git a/Source/Crunch/Private/Player/CPlayerController.cpp b/Source/Crunch/Private/Player/CPlayerController.cpp index e82c2c4..a1511b4 100644 --- a/Source/Crunch/Private/Player/CPlayerController.cpp +++ b/Source/Crunch/Private/Player/CPlayerController.cpp @@ -3,3 +3,24 @@ #include "Crunch/Public/Player/CPlayerController.h" +#include "Character/CPlayerCharacter.h" + +void ACPlayerController::OnPossess(APawn* InPawn) +{ + Super::OnPossess(InPawn); + CPlayerCharacter = Cast(InPawn); + if (CPlayerCharacter) + { + CPlayerCharacter->ServerSideInit(); + } +} + +void ACPlayerController::AcknowledgePossession(class APawn* P) +{ + Super::AcknowledgePossession(P); + CPlayerCharacter = Cast(P); + if (CPlayerCharacter) + { + CPlayerCharacter->ClientSideInit(); + } +} diff --git a/Source/Crunch/Public/Character/CCharacter.h b/Source/Crunch/Public/Character/CCharacter.h index c851781..22a7fc1 100644 --- a/Source/Crunch/Public/Character/CCharacter.h +++ b/Source/Crunch/Public/Character/CCharacter.h @@ -3,16 +3,19 @@ #pragma once #include "CoreMinimal.h" +#include "AbilitySystemInterface.h" #include "GameFramework/Character.h" #include "CCharacter.generated.h" UCLASS() -class CRUNCH_API ACCharacter : public ACharacter +class CRUNCH_API ACCharacter : public ACharacter, public IAbilitySystemInterface { GENERATED_BODY() public: ACCharacter(); + void ServerSideInit(); + void ClientSideInit(); protected: virtual void BeginPlay() override; @@ -21,4 +24,14 @@ public: virtual void Tick(float DeltaTime) 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; }; diff --git a/Source/Crunch/Public/GAS/CAbilitySystemComponent.h b/Source/Crunch/Public/GAS/CAbilitySystemComponent.h new file mode 100644 index 0000000..1ef37d0 --- /dev/null +++ b/Source/Crunch/Public/GAS/CAbilitySystemComponent.h @@ -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> InitialEffects; +}; diff --git a/Source/Crunch/Public/GAS/CAttributeSet.h b/Source/Crunch/Public/GAS/CAttributeSet.h new file mode 100644 index 0000000..8855b54 --- /dev/null +++ b/Source/Crunch/Public/GAS/CAttributeSet.h @@ -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& 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); +}; + diff --git a/Source/Crunch/Public/Player/CPlayerController.h b/Source/Crunch/Public/Player/CPlayerController.h index e66ec7c..96ad218 100644 --- a/Source/Crunch/Public/Player/CPlayerController.h +++ b/Source/Crunch/Public/Player/CPlayerController.h @@ -13,4 +13,14 @@ UCLASS() class CRUNCH_API ACPlayerController : public APlayerController { 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; + };