#memo

不正確な内容です、UE4についてが多い

仮想関数まわり、NativeEvent関数のオーバーライドについて

miyahuji111.hatenablog.com
NativeEvent、ImplementableEventについては上記を参考

通常のvirtual付き関数と、NativeEvent指定した関数の継承時の振る舞いについてまとめる

準備

AActor継承の適当なクラスを作成する、このクラスに適当に関数を適当に用意し、継承先のクラスで云々やってみる

標準の仮想関数について

virtual指定子をつけたりつけなかったりのやつを確認

UCLASS()
class ATestClass_A : public AActor
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable, Category = "TEST")
	FString A()
	{
		return TEXT("Called A() in TestClass_A");
	}

	UFUNCTION(BlueprintCallable, Category = "TEST")
	virtual FString B()
	{
		return TEXT("Called B() in TESTClass_A");
	}

};

UCLASS()
class ATestClass_B : public ATestClass_A
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable, Category = "TEST")
	FString A()
	{
		return TEXT("Called A() in TestClass_B");
	}

	UFUNCTION(BlueprintCallable, Category = "TEST")
	virtual FString B() override
	{
		return TEXT("Called B() in TESTClass_B");
	}

};

A()はオーバーロードでB()はオーバーライド、コンパイルしたらエディタでATestClass_A、ATestClass_Bオブジェクトをそれぞれ作成し、ATestClass_AのポインタとしてそれぞれのA()、B()を実行してみる

https://i.gyazo.com/d2613b8dca19b5e588ed2766a69731ce.png

はい

https://i.gyazo.com/2e41e33b506e01be0607f1e9320a4736.png

まとめ
  • C++の範囲内で収まるなら普通のvirtual指定子が普通な挙動する
  • BPエディタで実装の上書きはできない

純粋仮想関数

  • とりあえず後で

NativeEventのオーバーライド

本題、C++内でもオーバーライドしたいし、エディタでも処理を書きたい、書きたくない…?

/* コンパイル不可 */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "TEST")
virtual FString A();

正しいやり方はこれ

// .h
UCLASS()
class ATestClass_A : public AActor
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "TEST")
	FString A();
	virtual FString A_Implementation();
};

UCLASS()
class ATestClass_B : public ATestClass_A
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "TEST")
	FString A();
	virtual FString A_Implementation() override;
};

// .cpp
FString ATestClass_A::A_Implementation()
{
	return TEXT("in ATestClass_A");
}

FString ATestClass_B::A_Implementation()
{
	return TEXT("in ATestClass_B");
}

_Implemetation()をvirtual付きで宣言して、そちらをオーバーライドする、これだとBPエディタで更にオーバーライドも出来る、全クリ

https://i.gyazo.com/aafea36617a62869cf290203c32a94cf.png

How to overide BlueprintNativeEvent method from base class? - UE4 AnswerHub

おまけ: ImplementableEventを急に継承先でつける

/* コンパイル可 */
UCLASS()
class ATestClass_A : public AActor
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable, Category = "TEST")
	FString A()
	{
		return TEXT("in ATestClass_A");
	}

};

UCLASS()
class ATestClass_B : public ATestClass_A
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "TEST")
	FString A();
};
/* コンパイル不可 */
UCLASS()
class ATestClass_A : public AActor
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable, Category = "TEST")
	virtual FString A()
	{
		return TEXT("in ATestClass_A");
	}

};

UCLASS()
class ATestClass_B : public ATestClass_A
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable, Category = "TEST")
	virtual FString A() override;
};

なんかオーバーロードだとコンパイルが通る、しかしエディタでこの関数ををオーバーライドしようとしてみると

https://i.gyazo.com/9d331926739ea0863ed3c8e298509445.png

だめそう

まとめ
  • ImplementableEventは素直につかおう