第2章---初次接触GAS系统

文章详细描述了一个定制的AbilitySystemComponent(ASC)和RPGAttributeSet在游戏中的实现,涉及ASC的Owner和AvatarActor概念,以及在RPGGameCharacterBase、RPGGameEnemy、RPGGamePlayerCharacter和RPGPlayerState等类中的使用和复制模式设置。
摘要由CSDN通过智能技术生成

文件结构:

更新文件将高亮显示

  • Source
    • Private
      • AbilitySystemComponent
        • RPGAbilitySystemComponent.cpp
        • RPGAttributeSet.cpp
      • Character
        • PGGameCharacterBase.cpp
        • RPGGameEnemy.cpp
        • RPGGamePlayerCharacter.cpp
      • Game
        • RPGGameModeBase.cpp
      • Interaction
        • EnemyInterface.cpp
      • Player
        • RPGPlayerController.cpp
        • RPGPlayerState.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

文件表述:

RPGAbilitySystemComponent

定义一个自定义的ASC类

.h文件
// Copyright KimiLiu

#pragma once

#include "CoreMinimal.h"
#include "AbilitySystemComponent.h"
#include "RPGAbilitySystemComponent.generated.h"

/**
 * Ability System Component 拥有两个Owner: Owner Actor 以及Avatar Actor,这两个Actor有可能相同,有可能不相同
 *	Owner Actor 指的是实例化组件的Actor
 *	Avatar Actor 指的是ASC实际上服务的Actor,例如
 *		- RPGGameEnemy 内的ASC的 Owner Actor 和 Avatar Actor 都是 RPGGameEnemy 这个 Actor 类自身。因为ASC由 RPGGameEnemy 实例
 *			化,同时服务于 RPGGameEnemy
 *		- RPGGamePlayerCharacter 内的ASC的 Owner Actor 是 RPGPlayerState,而 Avatar Actor 是RPGGamePlayerCharacter。因为
 *			ASC由RPGPlayerState实例化,但是ASC服务于PRGGamePlayerCharacter
 */
UCLASS()
class AURA_API URPGAbilitySystemComponent : public UAbilitySystemComponent
{
	GENERATED_BODY()
	
};

.cpp文件
// Copyright KimiLiu


#include "AbilitySytstem/RPGAbilitySystemComponent.h"

RPGAttributeSet

新建一个自定义的属性集

.h文件
// Copyright KimiLiu

#pragma once

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

/**
 * 
 */
UCLASS()
class AURA_API URPGAttributeSet : public UAttributeSet
{
	GENERATED_BODY()
	
};

.cpp文件
// Copyright KimiLiu


#include "AbilitySytstem/RPGAttributeSet.h"

PGGameCharacterBase

.h文件

声明ASC组件以及AS组件,实现IAbilitySystemInterface接口内的GetAbilitySystemComponent()函数,新增GetAttributeSet()函数

// Copyright KimiLiu

#pragma once

#include "CoreMinimal.h"
#include "AbilitySytstem/RPGAbilitySystemComponent.h"
#include "AbilitySystemInterface.h"
#include "GameFramework/Character.h"
#include "RPGGameCharacterBase.generated.h"

class UAbilitySystemComponent;
class UAttributeSet;

UCLASS(Abstract)
class AURA_API ARPGGameCharacterBase : public ACharacter, public IAbilitySystemInterface
{
	GENERATED_BODY()

public:
	
	ARPGGameCharacterBase();

	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;

	UAttributeSet* GetAttributeSet() const {return AttributeSet;}

protected:
	
	virtual void BeginPlay() override;

	//后续开发尽量使用TObjectPtr<>来声明变量,可以给开发带来许多便利(蓝图内)
	UPROPERTY(EditAnywhere, Category="Combat")
	TObjectPtr<USkeletalMeshComponent> Weapon;

	//在此处声明GAS组件以及AttributeSet,但是只在Enemy类中实例化而不在PlayerCharacter中实例化
	//PlayerCharacter的GAS组件以及AttributeSet会在PlayerState中实例化(联网以及单机都可用)
	UPROPERTY()
	TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;

	UPROPERTY()
	TObjectPtr<UAttributeSet> AttributeSet;
};

.cpp文件

无改变

RPGGameEnemy

.h文件

无改变

.cpp文件

实例化父类声明的AbilitySystemComponent以及AttributeSet,在BeginPlay()函数中设置AbilitySystemComponent的两个Owner为该类本身

// Copyright KimiLiu


#include "..\..\Public\Character\RPGGameEnemy.h"

#include "AbilitySytstem/RPGAttributeSet.h"
#include "Aura/Aura.h"

ARPGGameEnemy::ARPGGameEnemy()
{
	GetMesh()->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);

	//实例化GAS组件,同时开启复制(复制相关功能只与网络有关)
	AbilitySystemComponent = CreateDefaultSubobject<URPGAbilitySystemComponent>("AbilitySystemComponent");
	AbilitySystemComponent->SetIsReplicated(true);

	AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Minimal);

	
	AttributeSet = CreateDefaultSubobject<URPGAttributeSet>("AttributeSet");
	
}

void ARPGGameEnemy::HighlightActor()
{
	
	GetMesh()->SetRenderCustomDepth(true);
	GetMesh()->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
	Weapon->SetRenderCustomDepth(true);
	Weapon->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
}

void ARPGGameEnemy::UnHighlightActor()
{
	GetMesh()->SetRenderCustomDepth(false);
	Weapon->SetRenderCustomDepth(false);
}

void ARPGGameEnemy::BeginPlay()
{
	Super::BeginPlay();
	
	AbilitySystemComponent->InitAbilityActorInfo(this, this);
}

RPGGamePlayerCharacter

.h文件

新增两个重写函数:PossessedBy()以及OnRep_PlayerState(),新增一个函数InitAbilityActorInfo()

// Copyright KimiLiu

#pragma once

#include "CoreMinimal.h"
#include "RPGGameCharacterBase.h"
#include "RPGGamePlayerCharacter.generated.h"

/**
 * 
 */
UCLASS()
class AURA_API ARPGGamePlayerCharacter : public ARPGGameCharacterBase
{
	GENERATED_BODY()

public:
	ARPGGamePlayerCharacter();

	virtual void PossessedBy(AController* NewController) override;
	virtual void OnRep_PlayerState() override;

private:
	void InitAbilityActorInfo();
};
.cpp文件
// Copyright KimiLiu


#include "Character\RPGGamePlayerCharacter.h"

#include "GameFramework/CharacterMovementComponent.h"
#include "Player/RPGPlayerState.h"

ARPGGamePlayerCharacter::ARPGGamePlayerCharacter()
{
	//角色始终面向移动方向
	GetCharacterMovement()->bOrientRotationToMovement = true;
	GetCharacterMovement()->RotationRate = FRotator(0.f, 400.f, 0.f);
	GetCharacterMovement()->bConstrainToPlane = true;//将运动约束在平面上

	//角色不会面向控制器的方向
	bUseControllerRotationPitch = false;
	bUseControllerRotationRoll = false;
	bUseControllerRotationYaw = false;

}

void ARPGGamePlayerCharacter::PossessedBy(AController* NewController)
{
	Super::PossessedBy(NewController);

	// Init ability actor info for the Sever
	InitAbilityActorInfo();
}

void ARPGGamePlayerCharacter::OnRep_PlayerState()
{
	Super::OnRep_PlayerState();

	// Init ability actor info for the Client
	InitAbilityActorInfo();
}

void ARPGGamePlayerCharacter::InitAbilityActorInfo()
{
	ARPGPlayerState* RPGPlayerState = GetPlayerState<ARPGPlayerState>();
	check(RPGPlayerState);
	RPGPlayerState->GetAbilitySystemComponent()->InitAbilityActorInfo(RPGPlayerState, this);
	
	//不在构造器内初始化,而是在被分配了Controller后将Controller内的AbilitySystemComponent和AttributeSet赋值给当前对象
	AbilitySystemComponent = RPGPlayerState->GetAbilitySystemComponent();
	AttributeSet = RPGPlayerState->GetAttributeSet();
}


RPGPlayerState

.h文件

声明ASC组件以及AS组件,实现IAbilitySystemInterface接口内的GetAbilitySystemComponent()函数,新增GetAttributeSet()函数

// Copyright KimiLiu

#pragma once

#include "CoreMinimal.h"
#include "AbilitySystemInterface.h"
#include "GameFramework/PlayerState.h"
#include "RPGPlayerState.generated.h"

class UAbilitySystemComponent;
class UAttributeSet;

/**
 * 
 */
UCLASS()
class AURA_API ARPGPlayerState : public APlayerState, public IAbilitySystemInterface
{
	GENERATED_BODY()

public:
	ARPGPlayerState();
	virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;

	UAttributeSet* GetAttributeSet() const {return AttributeSet;}

protected:
	UPROPERTY()
	TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;

	UPROPERTY()
	TObjectPtr<UAttributeSet> AttributeSet;
};

.cpp文件

注意看注释,注释写了不同的复制模式以及需要注意的点,在写单机游戏的时候将多人游戏一起考虑进去准没错

// Copyright KimiLiu


#include "Player/RPGPlayerState.h"

#include "AbilitySytstem/RPGAbilitySystemComponent.h"
#include "AbilitySytstem/RPGAttributeSet.h"

ARPGPlayerState::ARPGPlayerState()
{
	//服务器更新客户端频率,单机游戏不需要写,看需求,把多人的一起写了
	NetUpdateFrequency = 100.f;

	//实例化GAS组件,同时开启复制(复制相关功能只与网络有关)
	AbilitySystemComponent = CreateDefaultSubobject<URPGAbilitySystemComponent>("AbilitySystemComponent");
	AbilitySystemComponent->SetIsReplicated(true);


	/**
	 * Replication Mode :
	 *	Full:
	 *		-UseCase: Single player(单人游戏)
	 *		-Description: Gameplay Effects are replicated to all clients(GE会被所有客户端复制)
	 *	Mixed:
	 *		-UseCase: Multiplayer, Player-Controlled(多人游戏,玩家操作)
	 *		-Description: Gameplay Effects are replicated to the owning client only. Gameplay Cues and Gameplay Tags
	 *			replicated to all clients(GE会被拥有它的客户端复制, GC和GT会被所有客户端复制)
	 *		-OwnerActor's Owner must be the Controller. For Pawns, this is set automatically in PossessedBy();(当
	 *			Controller 被分配的时候,PossessedBy()这个函数会被调用,其他情况下PossessedBy()不会被调用,因此当我们项目中的某个类的
	 *			ASC的 Owner 的 Owner 不是Controller的时候,我们需要在这个类中主动调用SetOwner()来将这个类的Owner设置为Controller)
	 *		-By default, the PlayerState's Owner is automatically set to the Controller;
	 *		-Therefore, if your OwnerActor is not the PlayerState, and you use Mixed Replication Mode, you must call
	 *			SetOwner() on the OwnerActor to set its owner to the Controller;
	 *	Minimal:
	 *		-UseCase: Multiplayerm AI_Controlled(多人游戏,AI操作)
	 *		-Description: Gameplay Effects are not replicated. Gameplay Cues and Gameplay Tags replicated to all clients
	 *			(GE不会被复制,GC和GT会被所有客户端复制)
	 */
	AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);

	
	AttributeSet = CreateDefaultSubobject<URPGAttributeSet>("AttributeSet");
}

UAbilitySystemComponent* ARPGPlayerState::GetAbilitySystemComponent() const
{
	return AbilitySystemComponent;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

楚江_wog1st

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

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

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

打赏作者

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

抵扣说明:

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

余额充值