GAS代码部分

This commit is contained in:
2023-07-16 21:11:21 +08:00
parent c5985794c3
commit 2492b14434
19 changed files with 417 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
{
"BuildId": "0a363204-5da7-4021-aeb2-1b67bc780442",
"BuildId": "932c2020-a33d-4161-b628-beb96286e741",
"Modules":
{
"RD": "UnrealEditor-RD.dll",

View File

@@ -1,7 +1,7 @@
/Engine=C:/GitHub/UnrealEngine/Engine/Shaders
/ShaderAutogen=E:/UE5/TG_ARPG/Intermediate/ShaderAutogen
/Plugin/GLTFExporter=C:/GitHub/UnrealEngine/Engine/Plugins/Enterprise/GLTFExporter/Shaders
/Plugin/FX/Niagara=C:/GitHub/UnrealEngine/Engine/Plugins/FX/Niagara/Shaders
/Plugin/ExrReaderShaders=C:/GitHub/UnrealEngine/Engine/Plugins/Media/ImgMedia/Shaders
/Plugin/WmfMedia=C:/GitHub/UnrealEngine/Engine/Plugins/Media/WmfMedia/Shaders
/Plugin/GLTFExporter=C:/GitHub/UnrealEngine/Engine/Plugins/Enterprise/GLTFExporter/Shaders
/Plugin/Experimental/ChaosNiagara=C:/GitHub/UnrealEngine/Engine/Plugins/Experimental/ChaosNiagara/Shaders

View File

@@ -2,4 +2,93 @@
#include "TGAttributeSet.h"
#include "TGAbilitySystemComponent.h"
#include "GameplayEffect.h"
#include "GameplayEffectExtension.h"
#include "Net/UnrealNetwork.h"
UTGAttributeSet::UTGAttributeSet()
{
}
void UTGAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
Super::PostGameplayEffectExecute(Data);
if (Data.EvaluatedData.Attribute == GetcurrentHealthAttribute())
{
//限制范围
SetcurrentHealth(FMath::Clamp(GetcurrentHealth(), 0, GetmaxHealth()));
//广播变化
HealthChangeDelegate.Broadcast(GetcurrentHealth(), Data.EffectSpec.StackCount);
}
if (Data.EvaluatedData.Attribute == GetcurrentManaAttribute())
{
//限制范围
SetcurrentMana(FMath::Clamp(GetcurrentMana(), 0, GetmaxMana()));
//广播变化
ManaChangeDelegate.Broadcast(GetcurrentMana(), Data.EffectSpec.StackCount);
}
if (Data.EvaluatedData.Attribute == GetattackDamageAttribute())
{
//限制范围
SetattackDamage(FMath::Clamp(GetattackDamage(), 0, 100.0f));
//广播变化
AttackDamageChangeDelegate.Broadcast(GetattackDamage(), Data.EffectSpec.StackCount);
}
if (Data.EvaluatedData.Attribute == GetspeedMultiplierAttribute())
{
//限制范围
SetspeedMultiplier(FMath::Clamp(GetspeedMultiplier(), 0.1f, 2.0f));
//广播变化
SpeedMultiplierChangeDelegate.Broadcast(GetspeedMultiplier(), Data.EffectSpec.StackCount);
}
}
void UTGAttributeSet::OnRep_currentHealth(const FGameplayAttributeData& oldCurrentHealth)
{
//广播Gameplay Attribute中的数值网络同步
GAMEPLAYATTRIBUTE_REPNOTIFY(UTGAttributeSet,currentHealth,oldCurrentHealth);
}
void UTGAttributeSet::OnRep_maxHealth(const FGameplayAttributeData& oldMaxHealth)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UTGAttributeSet,maxHealth,oldMaxHealth);
}
void UTGAttributeSet::OnRep_currentMana(const FGameplayAttributeData& oldCurrentMana)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UTGAttributeSet,currentMana,oldCurrentMana);
}
void UTGAttributeSet::OnRep_maxMana(const FGameplayAttributeData& oldMaxMana)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UTGAttributeSet,maxMana,oldMaxMana);
}
void UTGAttributeSet::OnRep_attackDamage(const FGameplayAttributeData& oldAttackDamage)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UTGAttributeSet,attackDamage,oldAttackDamage);
}
void UTGAttributeSet::OnRep_speedMultiplier(const FGameplayAttributeData& oldSpeedMultiplier)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UTGAttributeSet,speedMultiplier,oldSpeedMultiplier);
}
void UTGAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION_NOTIFY(UTGAttributeSet,currentHealth,COND_None,REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UTGAttributeSet,maxHealth,COND_None,REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UTGAttributeSet,currentMana,COND_None,REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UTGAttributeSet,maxMana,COND_None,REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UTGAttributeSet,attackDamage,COND_None,REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UTGAttributeSet,speedMultiplier,COND_None,REPNOTIFY_Always);
//DOREPLIFETIME_CONDITION_NOTIFY(UTengenAttributeSet,Armor,COND_None,REPNOTIFY_Always);
}

View File

@@ -4,14 +4,91 @@
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "TGAbilitySystemComponent.h"
#include "TGAttributeSet.generated.h"
#define ATTRIBUTE_ACCESSORS(ClassName,PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName,PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
/**
*
*/
struct FGameplayEffectModCallbackData;
//创建代理
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FAttrChangeDelegate,float,Attr,int32,stackCount);
UCLASS()
class TG_ARPG_API UTGAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
UTGAttributeSet();
//在生命周期内,将对象设置为网络复制的对象
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
//定义各个参数和对应的OnRep/Notify参数
UPROPERTY(BlueprintReadOnly,Category = "Attribute",ReplicatedUsing = OnRep_currentHealth)
FGameplayAttributeData currentHealth;
ATTRIBUTE_ACCESSORS(UTGAttributeSet,currentHealth);
UPROPERTY(BlueprintReadOnly,Category = "Attribute",ReplicatedUsing = OnRep_MaxHealth)
FGameplayAttributeData maxHealth;
ATTRIBUTE_ACCESSORS(UTGAttributeSet,maxHealth);
UPROPERTY(BlueprintReadOnly,Category = "Attribute",ReplicatedUsing = OnRep_currentMana)
FGameplayAttributeData currentMana;
ATTRIBUTE_ACCESSORS(UTGAttributeSet,currentMana);
UPROPERTY(BlueprintReadOnly,Category = "Attribute",ReplicatedUsing = OnRep_MaxMana)
FGameplayAttributeData maxMana;
ATTRIBUTE_ACCESSORS(UTGAttributeSet,maxMana);
UPROPERTY(BlueprintReadOnly,Category = "Attribute",ReplicatedUsing = OnRep_attackDamage)
FGameplayAttributeData attackDamage;
ATTRIBUTE_ACCESSORS(UTGAttributeSet,attackDamage);
UPROPERTY(BlueprintReadOnly,Category = "Attribute",ReplicatedUsing = OnRep_speedMultiplier)
FGameplayAttributeData speedMultiplier;
ATTRIBUTE_ACCESSORS(UTGAttributeSet,speedMultiplier);
//UPROPERTY(BlueprintReadOnly,Category = "Attribute",ReplicatedUsing = OnRep_Armor)
//FGameplayAttributeData Armor;
//ATTRIBUTE_ACCESSORS(UTengenAttributeSet,Armor);
UPROPERTY(BlueprintReadOnly,Category = "Damage")
FGameplayAttributeData Damage;
ATTRIBUTE_ACCESSORS(UTGAttributeSet,Damage);
//数值变化时,通知所有绑定该代理的类
FAttrChangeDelegate HealthChangeDelegate;
FAttrChangeDelegate ManaChangeDelegate;
FAttrChangeDelegate AttackDamageChangeDelegate;
FAttrChangeDelegate SpeedMultiplierChangeDelegate;
//将返回值固定在合理范围内
void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;
//当数值发生变化时,在网络中广播该变化
UFUNCTION()
virtual void OnRep_currentHealth(const FGameplayAttributeData& oldCurrentHealth);
UFUNCTION()
virtual void OnRep_maxHealth(const FGameplayAttributeData& oldMaxHealth);
UFUNCTION()
virtual void OnRep_currentMana(const FGameplayAttributeData& oldCurrentMana);
UFUNCTION()
virtual void OnRep_maxMana(const FGameplayAttributeData& oldMaxMana);
UFUNCTION()
virtual void OnRep_attackDamage(const FGameplayAttributeData& oldAttackDamage);
UFUNCTION()
virtual void OnRep_speedMultiplier(const FGameplayAttributeData& oldSpeedMultiplier);
//UFUNCTION()
//virtual void OnRep_Armor(const FGameplayAttributeData& oldArmor);
};

View File

@@ -9,6 +9,8 @@
#include "GameFramework/SpringArmComponent.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "TGAbilitySystemComponent.h"
#include "TGAttributeSet.h"
//////////////////////////////////////////////////////////////////////////
@@ -16,8 +18,9 @@
ATG_ARPGCharacter::ATG_ARPGCharacter()
{
PrimaryActorTick.bCanEverTick = true;
// Set size for collision capsule
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
// GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
// Don't rotate when the controller rotates. Let that just affect the camera.
bUseControllerRotationPitch = false;
@@ -49,6 +52,11 @@ ATG_ARPGCharacter::ATG_ARPGCharacter()
// Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character)
// are set in the derived blueprint asset named ThirdPersonCharacter (to avoid direct content references in C++)
AbilitySystemComponent = CreateDefaultSubobject<UTGAbilitySystemComponent>("ACS Comp");
AbilitySystemComponent->SetIsReplicated(true); // 开启网络复制
AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed); // 使用Mixed可自动网络复制Gameplay Cue的相关逻辑或Minimal单机可以用Full
}
void ATG_ARPGCharacter::BeginPlay()
@@ -64,6 +72,26 @@ void ATG_ARPGCharacter::BeginPlay()
Subsystem->AddMappingContext(DefaultMappingContext, 0);
}
}
if (AbilitySystemComponent)
{
// 将AttributeSet设置为ACS的属性参数容器
AttributeSet = AbilitySystemComponent->GetSet<UTGAttributeSet>();
// 绑定预设的属性变化函数;当属性值变化时,触发绑定函数
const_cast<UTGAttributeSet*>(AttributeSet)->HealthChangeDelegate.AddDynamic(this, &ATG_ARPGCharacter::OnHealthChangeNative);
const_cast<UTGAttributeSet*>(AttributeSet)->ManaChangeDelegate.AddDynamic(this, &ATG_ARPGCharacter::OnManaChangedNative);
const_cast<UTGAttributeSet*>(AttributeSet)->AttackDamageChangeDelegate.AddDynamic(this, &ATG_ARPGCharacter::OnAttackDamageChangeNative);
const_cast<UTGAttributeSet*>(AttributeSet)->SpeedMultiplierChangeDelegate.AddDynamic(this, &ATG_ARPGCharacter::OnSpeedMultiplierChangedNative);
}
}
void ATG_ARPGCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
//////////////////////////////////////////////////////////////////////////
@@ -124,6 +152,141 @@ void ATG_ARPGCharacter::Look(const FInputActionValue& Value)
}
}
UAbilitySystemComponent* ATG_ARPGCharacter::GetAbilitySystemComponent() const
{
return AbilitySystemComponent;
}
void ATG_ARPGCharacter::OnHealthChangeNative(float health, int32 stackCount)
{
// 可以在C++中处理血量变化后的逻辑
// ***
// 也可以在蓝图中处理血量变化后的逻辑
OnHealthChange(health, stackCount);
}
void ATG_ARPGCharacter::OnManaChangedNative(float mana, int32 stackCount)
{
OnManaChanged(mana, stackCount);
}
void ATG_ARPGCharacter::OnAttackDamageChangeNative(float attackDamage, int32 stackCount)
{
OnAttackDamageChange(attackDamage, stackCount);
}
void ATG_ARPGCharacter::OnSpeedMultiplierChangedNative(float speedMultiplier, int32 stackCount)
{
OnSpeedMultiplierChanged(speedMultiplier, stackCount);
}
void ATG_ARPGCharacter::InitializeAbility(TSubclassOf<UGameplayAbility> abilityToGet, int32 abilityLevel)
{
// 仅在服务器端且ACS有效的情况下运行
if (HasAuthority() && AbilitySystemComponent)
{
AbilitySystemComponent->GiveAbility(FGameplayAbilitySpec(abilityToGet, abilityLevel, 0));
}
}
void ATG_ARPGCharacter::InitializeAbilities(TArray<TSubclassOf<UGameplayAbility>> abilitiesToGet, int32 abilityLevel)
{
// 遍历
for (TSubclassOf<UGameplayAbility> Abilities : abilitiesToGet)
{
InitializeAbility(Abilities, abilityLevel);
}
}
void ATG_ARPGCharacter::RemoveAbilityWithTags(FGameplayTagContainer tagContainer)
{
// 清除指定Tag数组的内容
TArray<FGameplayAbilitySpec*> localAbility;
AbilitySystemComponent->GetActivatableGameplayAbilitySpecsByAllMatchingTags(tagContainer, localAbility, true);
for (FGameplayAbilitySpec* Spec : localAbility)
{
AbilitySystemComponent->ClearAbility(Spec->Handle);
}
}
void ATG_ARPGCharacter::ChangeAbilityLevelWithTags(FGameplayTagContainer tagContainer, int32 newAbilityLevel)
{
// 更新含指定Tag的成员变量技能的等级
TArray<FGameplayAbilitySpec*> localAbility;
AbilitySystemComponent->GetActivatableGameplayAbilitySpecsByAllMatchingTags(tagContainer, localAbility, true);
for (FGameplayAbilitySpec* Spec : localAbility)
{
Spec->Level = newAbilityLevel;
}
}
void ATG_ARPGCharacter::CancelAbilityWithTags(FGameplayTagContainer withTags, FGameplayTagContainer withoutTags)
{
AbilitySystemComponent->CancelAbilities(&withTags, &withoutTags, nullptr);
}
void ATG_ARPGCharacter::PossessedBy(AController* newController)
{
Super::PossessedBy(newController);
AbilitySystemComponent->InitAbilityActorInfo(this, this); // 明确所属权
InitializeAbilities(InitialAbilites, 0); // 仅在服务端赋予具体Abilities注意Abilites不为空
}
void ATG_ARPGCharacter::OnRep_PlayerState()
{
Super::OnRep_PlayerState();
AbilitySystemComponent->InitAbilityActorInfo(this, this); // 明确所属权
}
void ATG_ARPGCharacter::GetCurrentHealthValues(float& currentHealth, float& maxHealth)
{
if (AttributeSet)
{
currentHealth = AttributeSet->GetcurrentHealth(); // 在AttributeSet中定义
maxHealth = AttributeSet->GetmaxHealth();
}
}
void ATG_ARPGCharacter::GetCurrentManaValues(float& currentMana, float& maxMana)
{
if (AttributeSet)
{
currentMana = AttributeSet->GetcurrentMana(); // 在AttributeSet中定义
maxMana = AttributeSet->GetmaxMana();
}
}
void ATG_ARPGCharacter::GetCurrentAttackDamageValues(float& currentAttackDamage)
{
if (AttributeSet)
{
currentAttackDamage = AttributeSet->GetattackDamage(); // 在AttributeSet中定义
}
}
void ATG_ARPGCharacter::GetCurrentSpeedMultiplierValues(float& currentSpeedMultiplier)
{
if (AttributeSet)
{
currentSpeedMultiplier = AttributeSet->GetspeedMultiplier(); // 在AttributeSet中定义
}
}
void ATG_ARPGCharacter::AddLooseGameplayTag(FGameplayTag tagToAdd)
{
AbilitySystemComponent->AddLooseGameplayTag(tagToAdd);
AbilitySystemComponent->SetTagMapCount(tagToAdd, 1); // Tag可以重名且拥有多个
}
void ATG_ARPGCharacter::RemoveLooseGameplayTag(FGameplayTag tagToRemove)
{
AbilitySystemComponent->RemoveLooseGameplayTag(tagToRemove);
}

View File

@@ -3,13 +3,18 @@
#pragma once
#include "CoreMinimal.h"
#include "AbilitySystemInterface.h"
#include "GameFramework/Character.h"
#include "GameplayEffect.h"
#include "InputActionValue.h"
#include "TG_ARPGCharacter.generated.h"
UCLASS(config=Game)
class ATG_ARPGCharacter : public ACharacter
class UTengenAbilityComponent;
class UTengenAttributeSet;
UCLASS()
class ATG_ARPGCharacter : public ACharacter , public IAbilitySystemInterface
{
GENERATED_BODY()
@@ -58,9 +63,87 @@ protected:
virtual void BeginPlay();
public:
virtual void Tick(float DeltaTime) override;
/** Returns CameraBoom subobject **/
FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
/** Returns FollowCamera subobject **/
FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
//加载ASC component
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = "GAS")
class UTGAbilitySystemComponent* AbilitySystemComponent;
//添加ASC数值
UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category = "GAS")
const class UTGAttributeSet* AttributeSet;
//初始化数值
UPROPERTY(EditDefaultsOnly,BlueprintReadOnly,Category ="GAS")
TArray<TSubclassOf<class UGameplayAbility>> InitialAbilites;
//接口函数
virtual class UAbilitySystemComponent* GetAbilitySystemComponent() const override;
//定义函数
UFUNCTION()
virtual void OnHealthChangeNative(float health,int32 stackCount);
UFUNCTION()
virtual void OnManaChangedNative(float mana,int32 stackCount);
UFUNCTION()
virtual void OnAttackDamageChangeNative(float attackDamage,int32 stackCount);
UFUNCTION()
virtual void OnSpeedMultiplierChangedNative(float speedMultiplier,int32 stackCount);
UFUNCTION(BlueprintImplementableEvent,Category = "Gas")
void OnHealthChange(float health,int32 stackCount);
UFUNCTION(BlueprintImplementableEvent,Category = "Gas")
void OnManaChanged(float mana,int32 stackCount);
UFUNCTION(BlueprintImplementableEvent,Category = "Gas")
void OnAttackDamageChange(float attackDamage,int32 stackCount);
UFUNCTION(BlueprintImplementableEvent,Category = "Gas")
void OnSpeedMultiplierChanged(float speedMultiplier,int32 stackCount);
//初始化ASC
UFUNCTION(BlueprintCallable,Category = "GAS")
void InitializeAbility(TSubclassOf<UGameplayAbility> abilityToGet,int32 abilityLevel);
UFUNCTION(BlueprintCallable,Category = "GAS")
void InitializeAbilities(TArray<TSubclassOf<UGameplayAbility>> abilitiesToGet,int32 abilityLevel);
//通过Tag删除指定Ability
UFUNCTION(BlueprintCallable,Category = "GAS")
void RemoveAbilityWithTags(FGameplayTagContainer tagContainer);
//通过Tag升级Ability信息
UFUNCTION(BlueprintCallable,Category = "GAS")
void ChangeAbilityLevelWithTags(FGameplayTagContainer tagContainer,int32 newLevel);
//通过Tag打断Ability释放效果
UFUNCTION(BlueprintCallable,Category = "GAS")
void CancelAbilityWithTags(FGameplayTagContainer withTags,FGameplayTagContainer withoutTags);
//Server初始化角色控制权
virtual void PossessedBy(AController* NewController) override;
//Client初始化角色控制权
virtual void OnRep_PlayerState() override;
//从GAS中获取属性值设定蓝图调用函数
UFUNCTION(BlueprintPure,Category = "GAS")
void GetCurrentHealthValues(float& CurrentHealth,float& maxHealth);
UFUNCTION(BlueprintPure,Category = "GAS")
void GetCurrentManaValues(float& CurrentMana,float& maxMana);
UFUNCTION(BlueprintPure,Category = "GAS")
void GetCurrentAttackDamageValues(float& currentAttackDamage);
UFUNCTION(BlueprintPure,Category = "GAS")
void GetCurrentSpeedMultiplierValues(float& currentSpeedMultiplier);
//附加仅本地使用的LooseGameplayTags网络不同步且手动管理
//通过一下函数调用在蓝图中管理LooseGamplayTags的数组TagMapCount;
UFUNCTION(BlueprintCallable, Category = "GAS")
void AddLooseGameplayTag(FGameplayTag tagToAdd);
UFUNCTION(BlueprintCallable, Category = "GAS")
void RemoveLooseGameplayTag(FGameplayTag tagToRemove);
};