📝

[UE5]GASメモ4 -GameplayEffectで回復ポーション作り-

2024/06/05に公開

前回の記事

https://zenn.dev/sayaivy/articles/gameplayability_3

更新情報

更新日 内容

前置き

読み飽きた方は飛ばしてください

この記事ではC++を使用します。
解説を挟みますが、ある程度わかる人向けです

また、現在個人製作中のゲーム"KillGurality"のプロジェクトを用いて記事を書いているので、プロジェクト名を使用するプレフィックスなどには"KG"を使用しています。
ソースコードをコピペする場合は、環境に合わせて置き換えてください。

環境
バージョン:UE5.2
エディタ:VSCode


C++プロジェクトの作り方や勉強は、こちらの記事を参考にしてください
とてもわかりやすく、無料パートだけでも参考になるかと思います。おすすめです
https://zenn.dev/posita33/books/ue5_starter_cpp_and_bp_001/viewer/chap_00_about

VSCodeを使っている方は、この設定をしておくと便利です。
https://dev.epicgames.com/documentation/ja-jp/unreal-engine/setting-up-visual-studio-code-for-unreal-engine#vsコード向けのintellisenseを設定する


この回では、とりあえずAttributeへ影響を与えてみるという簡単な部分のみの実装を行います。
ちゃんとしたGameplayEffectを使っての実装はまた別の記事で書こうと思っています
なので、プログラム的にあんまりよろしくないやり方を使って無理やり簡単Verを作成しています、ご了承ください

EffectActorの作成

Actorクラスを継承し、EffectActorクラスを作成します。

コードは以下の通りです。

EffectActor.h

#pragma once

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

class USphereComponent;

UCLASS()
class KILLGURALITY_API AKGEffectActor : public AActor
{
	GENERATED_BODY()
	
public:	
	AKGEffectActor();

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

	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;
};

エフェクトアクターに触れるとAttributeに影響を与えるようにOnOverlap関数を使います
ついでにコリジョンを抜けたときのEndOverlap関数もオーバーライドします

プライベート変数に、球状のコリジョンとスタティックメッシュを作成します。

EffectActor.cpp

#include "Actor/KGEffectActor.h"

#include "AbilitySystemComponent.h"
#include "AbilitySystemInterface.h"
#include "AbilitySystem/KGAttributeSet.h"
#include "Components/SphereComponent.h"

AKGEffectActor::AKGEffectActor()
{
	PrimaryActorTick.bCanEverTick = false;

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

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

}

void AKGEffectActor::OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{

	// TODO: 簡易化のため一時的にconst_castを使っているが、廃止予定
	if(IAbilitySystemInterface* ASInterface = Cast<IAbilitySystemInterface>(OtherActor))
	{
		const UKGAttributeSet* KGAttributeSet = Cast<UKGAttributeSet>(ASInterface->GetAbilitySystemComponent()->GetAttributeSet(UKGAttributeSet::StaticClass()));

		UKGAttributeSet* MutableKGAttributeSet = const_cast<UKGAttributeSet*>(KGAttributeSet);
		MutableKGAttributeSet->SetHealth(KGAttributeSet->GetHealth() + 50.f);

		Destroy();
	}
}

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

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

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

コンストラクタでは、プライベート変数として用意したメッシュとコリジョンをセットしているだけです。

OnOverlapイベントでは、OverlapしたアクターがAbilitySystemInterfaceを持っているか確認してから処理に入っていきます。
そして冒頭で前置きさせていただいた、あんまりよろしくない記述というのが、このconst→castのセットです。
KGAttributeSetは静的クラスであるためconstで宣言しているのに対し、それを塗り替えるようにcastを使って新しくKGAttributeを作成し、SetHealthで値を上書きしています。定数だって宣言しているのに値が変わってるという状況です。なんてこった
後で修正する予定なのでコメントを残しておきます

エディタで確認

先ほど作成したEffectActorクラスを継承し、ブループリントでポーションを作成します。
C++で作っておいたMeshコンポーネントにメッシュを設定します。
ポーションっぽい素材がないので、とりあえずShape_Sphereをセットしておきます。

alt text

メッシュとコリジョンをいい感じの大きさに合わせてレベルに配置し、実行します。

前回同様、実行時に@キーを押し、showdebug abilitysystemコマンドを叩きます
現在はEffectActorに触る前です。

alt text

EffectActorクラスに触れると以下のようになります

alt text

Healthが150に増えていますね
Attributeに影響を与えることができました

おわり

簡単にですが、Attributeに何かしらのアクションをかけることができました。
もうちょっと解像度上げて作ってみようと思いますが、それを次回やるかどうかは未定です

次回の内容は考え中...

GitHubで編集を提案

Discussion