【UE C++】インターフェースの使用方法

【UE C++】インターフェースの使用方法

1.コンセプト

インターフェイス クラスは、共通の親クラスを持たないが同じ機能を必要とする (おそらく) 無関係なクラスのグループによって、一連の共通機能を確実に実装するのに役立ちます。この場合、インターフェイスをお勧めします。

ネイティブ C++ にはインターフェイスがないため、C++ 開発者はインターフェイスの代わりに純粋な抽象クラスを使用します。UE では、インターフェイスを管理用のリフレクション システムに含めることを可能にするために、UInterface が導入されています。UInterface は UObject を継承しますが、UE 開発者がインターフェイスを使用する必要がある場合、UInterface を直接継承するとダイヤモンド継承の問題が発生します。仮想継承で軽減できますが、安全ではありません。したがって、インターフェイスを作成すると、2 つのクラスが存在します。2 番目のクラスは、開発者がインターフェイス関数を定義する場所です。このクラスはどのクラスからも継承されず、ダイアモンド継承を回避します。最初のクラスは UInterface から継承し、主にインターフェイス クラスをUE リフレクション システムに含めることができるようにします。

2. インターフェースの作成

新しい C++ クラス 一番下までスクロールして [Unreal Interface] を選択します。[すべてのクラスを表示] をクリックして選択しないでください。検索できません。

3. インターフェース関数の宣言

3.1 C++ での定義

UFUNCTION()
virtual void UFUNCTIONTesFun(float value) {};//UFunction虚函数

virtual void VirtualTestFun(float value) {};//普通虚函数,须有定义

virtual void PureVirtualTestFun(float value) = 0;//纯虚函数

予防:

  • インターフェイス関数を意味のあるものにするには、仮想関数として宣言する必要があります。virtual キーワードが追加されていない場合は、コンパイルが通らない可能性があります (UFUNCTION マークが付いています)。パスした場合は、関数のオーバーロードではなく、関数のオーバーライドになります。
  • 純粋でない仮想宣言された関数には、インターフェイス内に対応する定義が必要です。上記の例の"{}"は、コンパイルが失敗するのを防ぐために空の定義を使用しています。
  • Pure 仮想関数がインターフェイスに存在すると、C++ でこのインターフェイスを継承するクラスがその関数を実装する必要があります。実装しないとコンパイルが通過しません。このインターフェイスを実装するブループリント クラスは効果がありません

3.2 ブループリントで定義する

UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
void BlueprintImpTestFun(float value);//不能有virtual

UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void BlueprintNatTesFun(float value);//不能有virtual
virtual void BlueprintNatTesFun_Implementation(float value) {};//可以不在接口类中声明定义。只在实现自该接口的C++类中声明并定义

予防:

  • BlueprintCallableブループリント呼び出し可能としてマークされた関数も存在するBlueprintImplementableEventか、BlueprintNativeEventマークされている必要があります。同時に宣言された関数を仮想関数にすることはできません (ブループリントには仮想関数用の特別な処理メソッドがあります)
  • インターフェイス クラスを C++ でのみ実装したい場合、ブループリントではそれを実装できません。インターフェイス クラスは としてマークできますUINTERFACE(meta = (CannotImplementInterfaceInBlueprint))が、追加BlueprintImplementableEventまたはBlueprintNativeEventマークすることはできません。そうしないとコンパイルが通過しません。現時点では単独で存在しておりBlueprintCallable、この関数がブループリントから呼び出せることを示しています。

4. インターフェイス クラスを実装して使用する

これが私のインターフェースクラスです

UINTERFACE(MinimalAPI)
class UInterfaceTest : public UInterface
{
	GENERATED_BODY()
};

class STUDY427TEST_API IInterfaceTest
{
	GENERATED_BODY()

public:

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void BlueprintImpTestFun(float value);

	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	void BlueprintNatTesFun(float value);
	virtual void BlueprintNatTesFun_Implementation(float value) {};

	UFUNCTION()
	virtual void UFUNCTIONTesFun(float value) {};

	void NormalFun(float value);//此函数无作用,用于测试蓝图覆盖
	
	virtual void VirtualTestFun(float value) {};

	virtual void PureVirtualTestFun(float value) = 0;
};

4.1 インターフェースクラスの実装

上で述べたのは、IInterfaceTest開発者がインターフェイス関数を宣言する場所であるため、それを継承する必要があるため、リフレクションに使用される補助クラスUInterfaceTestです。

class STUDY427TEST_API AInterfaceTestActor : public AActor, public IInterfaceTest

4.2 インターフェイス クラスが実装されているかどうかを確認する

4.2.1 授業を通じて

ここで使用されているのは、UInterfaceTest判断するために反射が使用されていることです。

bool bIsImplemented = false;

bIsImplemented = this->GetClass()->ImplementsInterface(UInterfaceTest::StaticClass());

bIsImplemented = this->Implements<UInterfaceTest>();

Implements<UInterfaceTest>()実際に内部で呼び出されるGetClass()->ImplementsInterface(UInterfaceTest::StaticClass())メソッド

4.2.2 スルーキャスト

使用されるのはIInterfaceTest、C++ クラスがそれを継承するIInterfaceTestため、Cast オブジェクトがそれです。

IInterfaceTest* MyInterfaceTest = Cast<IInterfaceTest>(this);
if(MyInterfaceTest)
{
    //内部逻辑
}

注:ブループリント クラスは継承を介さずにインターフェイスを使用するため、このメソッドはブループリント クラスがインターフェイスを実装しているかどうかを判断できません。そのため、 Cast は無効ですClassによる判定方法(4.2.1)

4.3 インターフェース関数の呼び出し

4.3.1 C++で定義された関数

通常の C++ 関数呼び出しメソッドを使用するだけです

IInterfaceTest* MyInterfaceTest = Cast<IInterfaceTest>(TestActor);
if (MyInterfaceTest)
{
    MyInterfaceTest->UFUNCTIONTesFun(10.f);
    MyInterfaceTest->PureVirtualTestFun(20.0f);
    MyInterfaceTest->VirtualTestFun(30.0f);
}
4.3.2 ブループリントで定義された関数

それでも上記の方法を使用してIInterfaceTest::Execute_XXXXX(Actor, Parameter···)呼び出しを強制すると、エディタがクラッシュする可能性があります。

//使用之前判断是否实现该接口更保险
IInterfaceTest::Execute_BlueprintImpTestFun(this,50.0f);
IInterfaceTest::Execute_BlueprintNatTesFun(this, 60.0f);

参考リンク

おすすめ

転載: blog.csdn.net/qq_52179126/article/details/129979662
おすすめ