読者です 読者をやめる 読者になる 読者になる

ムラサメ研究ブログ

主にゲームやプログラミングのログ

UnrealEngine4 最初にBluePrintとのリフレクション部分を調べる part1 クラスの作成&継承

UnrealEngine4

UnrealEngine4 を初めて触る

インストールやセットアップは色々なサイトであるので、私は 最新のUnrealEngine4のソースをダウンロードし、エンジンビルドを行い BluePrintとのリフレクション部分を調べた 理由は、程よい難易度で、UnrealEngineの全体像を軽く理解できると思ったので

クラス作成

C++クラス作成

Unreal Engine | 2 - C++ クラスを作成する

メニューから

f:id:murasame-labo:20160906213727j:plain

とりあえずActor選び

f:id:murasame-labo:20160906213729j:plain

f:id:murasame-labo:20160906213824j:plain

アクター名つける

f:id:murasame-labo:20160906213727j:plain

そしてコンパイルする! VisualStudioソリューションを作成しビルドするもよし、エディタのホットリロードするもよし

BluePrintで継承する

BluePrint新規作成

f:id:murasame-labo:20160906215151p:plain

先ほど作ったクラスを親に(MyActor)

f:id:murasame-labo:20160906215154p:plain

とりあえずこれで、C++クラスを継承したBluePrintができた。

C++とBluePrintをリフレクションする場合には、C++でクラスを作成しBluePrintで継承する

C++コードを見る

C++のコード(MyActor.h)をみてみる

#pragma once

#include "GameFramework/Actor.h"
#include "MyActor.generated.h"

UCLASS()
class HOGE_API AMyActor : public AActor
{
    GENERATED_BODY()
    
public:   
    // Sets default values for this actor's properties
    AMyActor();

    // Called when the game starts or when spawned
    virtual void BeginPlay() override;
    
    // Called every frame
    virtual void Tick( float DeltaSeconds ) override;

    
    
};

上記が自動生成されたコード。

AActorクラスを継承している。 Unrealではクラス名の頭に意味があり Uがつくものは UObject、AはActorを継承している Fもある

コンストラクタ、BeginPlay、Tickが用意されている

BeginPlayはワールドに生成された時、Tickは毎フレーム呼ばれるコールバック

ここで疑問が何個かあるとおもう

#include "MyActor.generated.h"

自動生成されたヘッダファイル。 ヘッダを変更するとUnrealBuildToolが自動的に生成する リフレクション用のファイル 自動生成されるので気にする必要はない

UCLASS()

コードをおうと

#if UE_BUILD_DOCS
#define UCLASS(...)
#else
#define UCLASS(...) BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_PROLOG)
#endif

#define BODY_MACRO_COMBINE_INNER(A,B,C,D) A##B##C##D
#define BODY_MACRO_COMBINE(A,B,C,D) BODY_MACRO_COMBINE_INNER(A,B,C,D)

とりあえず あまり気にせず、Unrealに管理させるクラスには UCLASS() が必要と。

HOGE_API

HOGEはプロジェクト名 これも気にしない

: public AActor

Actorから継承させなければ、Unrealの色々な機能が使えない。 UObject、AActor、ACharacter・・等色々あるが今回は AActorで行う

GENERATED_BODY()

#define GENERATED_BODY(...) BODY_MACRO_COMBINE(CURRENT_FILE_ID,_,__LINE__,_GENERATED_BODY)
#define BODY_MACRO_COMBINE_INNER(A,B,C,D) A##B##C##D
#define BODY_MACRO_COMBINE(A,B,C,D) BODY_MACRO_COMBINE_INNER(A,B,C,D)

これも特に気にせず、Unrealに管理させる場合に必要とおぼえておこう

Unrealに管理させるとは

BluePrintでは明示的にオブジェクトの削除が出来ず、ガーベージコレクションでメモリ管理を行う また BluePrintと連携するには、リフレクション機能が必要(おそらくDLLのような形ではないか?) のため AActorの継承、UCLASS()、GENERATED_BODY() の明記 が必要になる

実際の BluePrintとの連携は 次回