愛をもってゲームをつくるゴリラのブログ

UE5勉強中のゴリラがいろいろ頑張ります。

GameplayAbility - AttributeSet の準備編

こんばんは、ごりです。

今日はこちらの記事の続きからです。
goolee.hatenablog.com


今回は GameplayAbility を使う上で必要となってくるパラメータをまとめたクラスの準備をしていきます。
UE4サンプルの ActionRPG では キャラクターのステータスとして使っています。

前回作成した GPAStudy プロジェクトを起動して、 新規C++クラスを追加します。
f:id:m-goolee-y:20181129224335p:plain

右上の 全てのクラスを表示にチェックをして AttributeSet と検索します。

f:id:m-goolee-y:20181201000909p:plain

「AttributeSet」を選択して次へをクリック。

ファイル名は 「AttributeSetBase」 とします。
今回はソースコードを記述していきます。
説明はコメントで省略いたします。
まず AttributeSetBase.h です。

/**
*@file	 AttributeSetBase.h
*@brief  GameplayAbility で用いるパラメータの集合
*@author goolee
*@date	 2018/12/01
*/
#pragma once

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

/** 
 *  @def
 *  AttributeSet.h で定義されている
 *  Attribute への Setter, Getter を定義するためのマクロ
 */
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
	GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
	GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)

/**
 * @class
 * GameplayAbilityで用いるキャラクターのパラメータをまとめたクラス
 */
UCLASS()
class GPASTUDY_API UAttributeSetBase : public UAttributeSet
{
	GENERATED_BODY()
	
public:

	/**
	 * @fn
	 * コンストラクタ
	 */
	UAttributeSetBase();

	/**
	 * Blueprintから読み取り可能な キャラクターの体力を表す変数
	 * マクロで Setter,Getterを定義しているので、 SetHealth(), GetHealth()が呼び出し可能
	 */
	UPROPERTY(BlueprintReadOnly, Category="Health", ReplicatedUsing = OnRep_Health)
	FGameplayAttributeData Health;
	ATTRIBUTE_ACCESSORS( UAttributeSetBase, Health )

	/**
	 * @fn
	 * レプリケートされるAttributeSetの変数を取得する
	 * @brief  この関数の中で DOREPLIFTIME マクロを用いてレプリケートされた変数として追加する
	 * @return (OutLifeTimeProps) 
	 */
	virtual void GetLifetimeReplicatedProps( TArray<FLifetimeProperty>& OutLifetimeProps ) const override;

protected:

	/**
	 * @fn
	 * Healthの値が変更された際に呼び出される処理
	 */
	UFUNCTION()
	virtual void OnRep_Health();
};

つづいて、 AttributSet.cpp です。

#include "AttributeSetBase.h"
#include "Net/UnrealNetwork.h"

UAttributeSetBase::UAttributeSetBase() : Health(10.0f){
}

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

	DOREPLIFETIME( UAttributeSetBase, Health );
}

void UAttributeSetBase::OnRep_Health() {
	GAMEPLAYATTRIBUTE_REPNOTIFY(UAttributeSetBase, Health);
}

GetLifetimeReplicatedProps() と OnRepHealth() は マルチプレイヤーゲームを
作る際に必要となる処理です。
ブログを読んでいる方でマルチプレイヤーゲームを作りたい方は
こちらを記述してください。
そうでない方は、この二つの関数を記述していなくても大丈夫です。
間違ってたら連絡ください...

ではこのAttributeSetをキャラクターに持たせていきます。
前回作成した CharacterBase クラスに書いていきます。
まず CharacterBase.h です。

/**
*@file	 CharacterBase.h
*@brief  GameplayAbility を用いる キャラクターの基底クラス
*@author goolee
*@date	 2018/12/01
*/
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "AttributeSetBase.h"
#include "CharacterBase.generated.h"

UCLASS()
class GPASTUDY_API ACharacterBase : public ACharacter
{
	GENERATED_BODY()

public:
	
	/**
	 * @fn
	 * コンストラクタ
	 */
	ACharacterBase();

protected:

	/**
	 * キャラクターのステータス 
	 * ブループリントから呼び出しはできないが、
	 * ガベージコレクションに追加するため UPROPERTY() を記述
	 */
	UPROPERTY()
	UAttributeSetBase* AttributeSet;

	/**
	 * @fn
	 * ゲーム開始時や、生成時に呼ばれる処理
	 */
	virtual void BeginPlay() override;

	/**
	 * @fn
	 * キャラクターの体力を取得
	 *@return キャラクターの体力
	 */
  UFUNCTION(BlueprintCallable)
	virtual float GetHealth() const;

public:	

	/**
	 * @fn
	 * 毎フレーム呼ばれる処理
	 */
	virtual void Tick(float DeltaTime) override;

};

キャラクターに AttributeSetBase 型の変数と 
AttributeSet内の体力を取得する関数を宣言しました。

つづいて CharacterBase.cpp です。

#include "CharacterBase.h"

ACharacterBase::ACharacterBase()
{
    //trueにすると毎フレームTick関数を呼び出す設定
	PrimaryActorTick.bCanEverTick = true;

	//AttributeSet の生成
	AttributeSet = CreateDefaultSubobject<UAttributeSetBase>(TEXT("AttributeSet"));
}

void ACharacterBase::BeginPlay()
{
	Super::BeginPlay();
	
}

void ACharacterBase::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

float ACharacterBase::GetHealth() const {
	return AttributeSet->GetHealth();
}

今回ソースコードに追加するのはここまでです。
ここまで書いたらビルドしてプロジェクトに戻ってください。

コンテンツブラウザの C++クラスフォルダ内の CharacterBase を右クリックして
「CharacterBaseに基づくブループリントクラスを作成します」をクリック。
名前は 「BP_CharacterBase」とします。
フォルダは わかりやすくコンテンツ直下にします。

f:id:m-goolee-y:20181201021037p:plain

作成されると、BP_CharacterBaseが開かれると思います。
イベントグラフで 右クリックして GetHealth と打ってみましょう。

f:id:m-goolee-y:20181201022000p:plain

無事にでてきましたね。

BeginPlay から printString で 値の確認をしてみましょう。

f:id:m-goolee-y:20181201022119p:plain

起動時の ThirdPersonExampleMap に追加して、実行してみます。

f:id:m-goolee-y:20181201022354p:plain

上の写真のように表示されればOKです。


これでAttributeSetの準備が完了しました。
今回はここまでとします。

次回からは GameplayAbility を使うためのコンポーネントを準備していきます。

今日の内容でわからないことがあればご連絡ください。

ではでは。