UE4 インターフェイスについてのメモ
概要
UnrealEngine のインターフェイスについてのメモ書きです。
環境
Windows10
Visual Studio 2017
UnrealEngine 4.25
参考
以下を参考にさせて頂きました、ありがとうございます。
Unreal Engine : 公式
【Unreal C++】⑥Interface【UE4】
Interfaces In C++ | UE4 Community Wiki
【UE4】InterfaceとDispatcherの使い分け方-自分流
インターフェイスについて
インターフェイスは実装を縛る仕組みでクラスの依存度を下げるのに有用です。
C++にはインターフェイスがないため継承や純粋仮想クラスを使ったインターフェイスクラスで実現していますが、Unreal C++ も似たような感じのようです。
BPにてアクセスしたい相手BPクラスにキャストするケースがありますが、こういう場合にインターフェイスを使うことが望ましいようです。これはBPの参照が増えることによるビルド時間が延びてしまうことを抑えることができるためだと思われます。
Unreal C++ でのインターフェイス作成1
インターフェイス定義
UInterface
を継承したクラスを宣言し、UプリフィックスをIに変えたクラスを宣言し、実装を縛るメソッドを宣言します。この時、GENERATED_***_BODY() が U
と I
で違うことに注意。
またメタ情報の CannotImplementInterfaceInBlueprint
はC++での実装に制限する指定です。
#pragma once
#include "CoreMinimal.h"
#include "MyIntarface.generated.h"
UINTERFACE(BlueprintType, meta = (CannotImplementInterfaceInBlueprint))
class MYPROJECT2_API UPerson : public UInterface
{
GENERATED_UINTERFACE_BODY()
};
class MYPROJECT_API IPerson
{
GENERATED_IINTERFACE_BODY()
public:
// 実装したいメソッド
virtual FString Greeting();
};
Uプリフィックスのコンストラクタと、Iプリフィックスの実装メソッドデフォルト実装を書きます。この時点でインターフェイスぽくないです。。
#include "MyInterface.h"
UPerson::UPerson(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
FString IPerson::Greeting()
{
return( FString(TEXT("....")) );
}
C++でインターフェイスを実装する
あとはインターフェイスクラスを継承してクラス宣言します。
UCLASS()
class MYPROJECT_API UJapanese : public UObject, public IPerson
{
GENERATED_BODY()
public:
// オーバーライドする
virtual FString Greeting() override { return( FString::Printf(TEXT("こんにちは!")) ); }
};
デフォルト実装を持っているので、そちらを呼び出すこともできます。
UCLASS()
class MYPROJECT_API UAmerican : public UObject, public IPerson
{
GENERATED_BODY()
public:
// 元の実装を呼び出す
virtual FString Greeting() override { return(IPerson::Greeting()); }
};
Unreal C++ でのインターフェイス作成2
インターフェイス定義
BlueprintImplementableEvent
BlueprintNativeEvent
をつけたインターフェイスを定義します。
#pragma once
#include "MySampleInterface.generated.h"
UINTERFACE(Blueprintable)
class UMySampleInterface : public UInterface
{
GENERATED_UINTERFACE_BODY()
};
class IMySampleInterface
{
GENERATED_IINTERFACE_BODY()
public:
UFUNCTION(Category="Test", BlueprintImplementableEvent, BlueprintCallable)
void Func0();
UFUNCTION(Category="Test", BlueprintImplementableEvent, BlueprintCallable)
void Func0Arg(int32 Value);
UFUNCTION(Category="Test", BlueprintNativeEvent, BlueprintCallable)
int32 Func1();
UFUNCTION(Category="Test", BlueprintNativeEvent, BlueprintCallable)
int32 Func1Arg(int32 Value);
};
#include "MySampleInterface.h"
UMySampleInterface::UMySampleInterface(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
実装インターフェイス
呼び出しテスト
以下のコードを使ってインターフェイスの呼び出しを行います。
#include "Kismet/GameplayStatics.h"
TArray<AActor*> _TargetActors;
// インターフェース取得
UGameplayStatics::GetAllActorsWithInterface(this->GetWorld(), UMySampleInterface::StaticClass(), _TargetActors);
// インターフェースを実行
for (auto _Actor : _TargetActors)
{
IMySampleInterface::Execute_Func0(_Actor);
IMySampleInterface::Execute_Func0Arg(_Actor, 100);
IMySampleInterface::Execute_Func1(_Actor);
IMySampleInterface::Execute_Func1Arg(_Actor, 200);
}
継承インターフェイス
実装インターフェイスの場合と同様に実装でき、同様の結果になります。
BPでインターフェイスを実装する
BPエディタで開いて
[クラス設定] -> [詳細] -> [インターフェイス] で追加できます。
CannotImplementInterfaceInBlueprint
を付与したインターフェイスは実装インターフェイスでは追加できません。
継承インターフェイス
はBPが継承したクラスが実装しているインターフェイスが表示されます。
BP でのインターフェイス作成
インターフェイス定義
コンテンツフォルダから右クリックで「ブループリントインターフェイス」で作成できます。
BPインターフェイスにて関数名や引き数、返り値が設定できます。
BPクラスでの実装
このBPインターフェイスを実装したいBPクラスに対し実装インターフェイスで追加して使用します。[クラス設定] -> [詳細] -> [インターフェイス]
追加するとインターフェイスイベントを実装できるようになります。
まとめ
UEのインターフェイスはイベントメッセージ的な面が強い気がします。
クラスの依存度を下げるためにも積極的に使っていきたいところですが、定義の記述方法はもう少しどうにかなりませんかね。。
Author And Source
この問題について(UE4 インターフェイスについてのメモ), 我々は、より多くの情報をここで見つけました https://qiita.com/unknown_ds/items/bbe94534048ac50fb4b9著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .