UE4/c++ リフレクションについてまとめてみる
リフレクションは、ueのエディタやBluePrintとC++のソース間の通信を行ったり、c++では本来サポートされていないガベージコレクションやシリアライゼーションを実現するためのサポートをしているUnrealEngine独自のプロパティシステム。
UnrealEngineでソースファイルを作成すると、
#include "FileName.generated.h"
がヘッダファイルの先頭に書かれるが、これはリフレクション用にUHT(Unreal Build Tool)が自動生成しているファイルで、UBT(Unreal Build Tool)によってスキャンされたリフレクションデータを取り込んで、更新される。
基本的には、ヘッダファイルでリフレクションしたい型やプロパティにUENUM(), UCLASS(), USTRUCT(), UFUNCTION() ,UPROPERTY()といったアノーションをつけることで、プロジェクトをコンパイルする際にUBTに記憶されるってことらしい。
具体的な使い方を見ていくと、
UCLASS()
- UnrealEngineにおいてクラスを管理する際に必要で、宣言するときに指定子を使用することで抽象クラスであることを明示的にして、 アンリアルのエディタでワールドに追加されないようにする、なんてこともできる。基本に使う分にはソースを生成したときに自動的に 書かれるやつをそのまま使えば大丈夫。
UENUM()
- 列挙子(enum class)を宣言する際に必要。クラス内で内部的に使う分には問題ないけど、BluePrintでも使いたい場合や、 クラス外で定義したいときにはつける必要がある。
(コード例)
UENUM(BlueprintType)
enum class color {
red,
blue,
green
};
USTURUCT()
- 構造体をBlueprintにも公開したいときに使う。ただし、これだけだとガベージコレクションに入らないらしく、メンバに対してひとつづつUPROPERTYの設定がいる。それ以外は基本的にUCLASS()と同じ。
UPROPERTY()
- クラスの変数などをBlueprintに公開するときなどに使う。指定子の第一引数では、アクセス権をいじることができる。たとえば、EditAnywhereにするとエディタとかBlueprint上のどこからでもいじれるし、BlueprintReadOnlyにするとBlueprint上で読み出すことだけ可能にすることができる。第二引数では、その変数に対してカテゴリーを割り当てることができて、Blueprint上で検索をかけるときなどに活用することができる。
(コード例)
UPROPERTY(BlueprintReadOnly, Category = "hoge")
float _hoge;
UFUNCTION()
- UPROPERTY()の関数版。こちらも同様にアクセス権とかカテゴリーの指定ができる。
(コード例)
UFUNCTION(BluePrintCallable, Category = "hoge")
void Func(){ };
指定子に関しては、公式のドキュメントにほかにもたくさんあったので、触りながら覚えていくのがよさそうな気がする。
プロパティについてはつけないとエラーが出る場合もあるので、Blueprintのことも考えつつ、うまいこと付き合っていきたいですね。