第3章---初始化AttributeSet文件

文件结构:

更改文件将高亮显示

Source

  • Private
    • AbilitySystemComponen
      • RPGAbilitySystemComponent.cpp
      • RPGAttributeSet.cpp
    • Character
      • PGGameCharacterBase.cpp
      • RPGGameEnemy.cpp
      • RPGGamePlayerCharacter.cpp
    • Game
      • RPGGameModeBase.cpp
    • Interaction
      • EnemyInterface.cpp
    • Player
      • RPGPlayerController.cpp
      • RPGPlayerState.cpp
    • Actor
      • RPGEffectActor.cpp
  • Public
    • AbilitySystemComponent
      • RPGAbilitySystemComponent.h
      • RPGAttributeSet.h
    • Character
      • RPGGameCharacterBase.h
      • RPGGameEnemy.h
      • RPGGamePlayerCharacter.h
    • Game
      • RPGGameModeBase.h
    • Interaction
      • EnemyInterface.h
    • Player
      • RPGPlayerController.h
      • RPGPlayerState.h
    • Actor
      • RPGEffectActor.h

文件表述:

RPGAttributeSet

.h文件

新增四个属性,同时考虑多人游戏情况

// Copyright KimiLiu

#pragma once

#include "CoreMinimal.h"
#include "AbilitySystemComponent.h"
#include "AttributeSet.h"
#include "RPGAttributeSet.generated.h"

#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
	GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)

/**
 * AS拥有预测功能(Prediction)能够让多人游戏的客户端在拥有更少的延迟。客户端能够立刻改变自己维护的AS,然后通知服务端,由服务端判定这个更
 *	改是否合法,如果不合法,则服务端拒绝更改AS并通知客户端回滚AS
 */
UCLASS()
class AURA_API URPGAttributeSet : public UAttributeSet
{
	GENERATED_BODY()

public:
	URPGAttributeSet();

	//复制变量时必须重写的函数,用于注册需要复制的变量
	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

	/**
	 * 创建AS属性步骤:
	 *	1. 声明FGameplayAttributeData类型变量
	 *	2. 用UPROPERTY()宏修饰
	 *	3. 如果是多人游戏,需要在宏内声明: ReplicatedUsing = OnRep_属性名,同时声明一个UFUNCTION()方法OnRep_属性名()。当服务端的该属性
	 *		值变化时,OnRep_属性名()将会被调用,我们在这个函数内处理变化事件
	 *	4. 实现OnRep_属性名()函数,在函数内调用GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, 属性名, 旧属性值)宏,用来保存旧值用于
	 *		服务端通知客户端进行回滚
	 *	5. 重写GetLifetimeReplicatedProps()函数,在该函数内注册属性
	 *	6. 使用ATTRIBUTE_ACCESSORS()宏来初始化value_getter, property_getter, value_setter, initter
	 */
	
	UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health, Category="Vital Attribute")
	FGameplayAttributeData Health;
	ATTRIBUTE_ACCESSORS(URPGAttributeSet, Health);

	UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_MaxHealth, Category="Vital Attribute")
	FGameplayAttributeData MaxHealth;
	ATTRIBUTE_ACCESSORS(URPGAttributeSet, MaxHealth);
	
	UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Mana, Category="Vital Attribute")
	FGameplayAttributeData Mana;
	ATTRIBUTE_ACCESSORS(URPGAttributeSet, Mana);

	UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Mana, Category="Vital Attribute")
	FGameplayAttributeData MaxMana;
	ATTRIBUTE_ACCESSORS(URPGAttributeSet, MaxMana);

	UFUNCTION()
	void OnRep_Health(const FGameplayAttributeData& OldHealth) const;

	UFUNCTION()
	void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const ;

	UFUNCTION()
	void OnRep_Mana(const FGameplayAttributeData& OldMana) const;

	UFUNCTION()
	void OnRep_MaxMana(const FGameplayAttributeData& OldMaxMana) const;
};

.cpp文件

函数实现

// Copyright KimiLiu


#include "AbilitySytstem/RPGAttributeSet.h"
#include "Net/UnrealNetwork.h"

URPGAttributeSet::URPGAttributeSet()
{
    
}

void URPGAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);

    //注册需要复制的属性Health,没有复制条件,不论复制的结果是否等于客户端原有结果,都进行复制调用
    DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, Health, COND_None, REPNOTIFY_Always);
    DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
    DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, Mana, COND_None, REPNOTIFY_Always);
    DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, MaxMana, COND_None, REPNOTIFY_Always);
}

void URPGAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) const 
{
    //当Health属性被调用,此函数被调用,传入OldHealth作为旧值,该旧值将会被保存以免服务端通知客户端该属性需要回滚
    GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, Health, OldHealth);
}

void URPGAttributeSet::OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const 
{
    GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, Health, OldMaxHealth);
}

void URPGAttributeSet::OnRep_Mana(const FGameplayAttributeData& OldMana) const
{
    GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, Mana, OldMana);
}

void URPGAttributeSet::OnRep_MaxMana(const FGameplayAttributeData& OldMaxMana) const
{
    GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, MaxMana, OldMaxMana);
}

RPGEffectActor

对AttributeSet内的属性值做出改变的物体的父类,有可能是各种药水,或是某个陷阱。

.h文件

声明一个静态网格体以及一个碰撞体

// Copyright KimiLiu

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "RPGEffectActor.generated.h"

class USphereComponent;
class UStaticMeshComponent;

UCLASS()
class AURA_API ARPGEffectActor : public AActor
{
	GENERATED_BODY()
	
public:
	ARPGEffectActor();

	UFUNCTION()
	virtual void OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

	UFUNCTION()
	virtual void EndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

protected:
	virtual void BeginPlay() override;

private:
	UPROPERTY(VisibleAnywhere)
	TObjectPtr<USphereComponent> Sphere;

	UPROPERTY(VisibleAnywhere)
	TObjectPtr<UStaticMeshComponent> Mesh;

};
.cpp文件
// Copyright KimiLiu


#include "Actor/RPGEffectActor.h"

#include "AbilitySystemComponent.h"
#include "AbilitySystemInterface.h"
#include "AbilitySytstem/RPGAttributeSet.h"
#include "Components/SphereComponent.h"

// Sets default values
ARPGEffectActor::ARPGEffectActor()
{
	PrimaryActorTick.bCanEverTick = false;

	Mesh = CreateDefaultSubobject<UStaticMeshComponent>("Mesh");
	SetRootComponent(Mesh);

	Sphere = CreateDefaultSubobject<USphereComponent>("Sphere");
	Sphere->SetupAttachment(GetRootComponent());
	
}

void ARPGEffectActor::OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (IAbilitySystemInterface* ASCInterface = Cast<IAbilitySystemInterface>(OtherActor))
	{
		//可以获取到指定对象的AttributeSet, 对于PlayerCharacter来说,在Possedby()函数内已经给PlayerCharacter的AttributeSet和
		//AbilitySystemComponent赋值了,赋的值是PlayerState内的AttributeSet和AbilitySystemComponent
		const URPGAttributeSet* RPGAttributeSet =Cast<URPGAttributeSet>(ASCInterface->GetAbilitySystemComponent()->GetAttributeSet(URPGAttributeSet::StaticClass()));
		GEngine->AddOnScreenDebugMessage(1, 2.0f, FColor::Red, FString("Character On Overlapped"));
		Destroy();
	}
	
}

void ARPGEffectActor::EndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	
}

void ARPGEffectActor::BeginPlay()
{
	Super::BeginPlay();

	Sphere->OnComponentBeginOverlap.AddDynamic(this, &ARPGEffectActor::OnOverlap);
	Sphere->OnComponentEndOverlap.AddDynamic(this,&ARPGEffectActor::EndOverlap);
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楚江_wog1st

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值