Featured image of post [UE5] 『Add C++ Class』ウィザードが自動生成するコードの内容をカスタマイズする (既存項目編集編)

[UE5] 『Add C++ Class』ウィザードが自動生成するコードの内容をカスタマイズする (既存項目編集編)

UE 5.1.1

はじめに

Unreal Editor には、C++ コード生成ウィザード『Add C++ Class』が備わっています。

(Unreal Editor → メニュー → ToolsNew C++ Class... から呼び出せます)

「選択したクラスを継承したクラスの雛形となる C++ コード (.h, .cpp) を自動生成して、プロジェクトに追加してくれる」というものなのですが、「自動生成されるコードをカスタマイズできないか」と考えて調べてみたところ、以下のことがわかりました。

  • ① 対応する Template ファイルが存在するクラスであれば、エンジンビルドなしでカスタマイズできる (Launcher 版でも OK)
  • ② 対応する Template ファイルが存在しないクラスの場合、エンジンコードの修正とビルドが必要になる

今回は、上記 ① の場合の手順について解説します。

カスタマイズ方法

カスタマイズしたいクラスに対応する Template ファイルを見つけて、それをテキストエディタで編集するだけです。

Template ファイルの格納ディレクトリ

Template ファイルは、以下の場所にあります。

《エンジンディレクトリ》/Engine/Content/Editor/Templates/

  • プラットフォームが Windows
  • Editor が Launcher 版
  • エンジンインストールディレクトリをデフォルトから変更していない

という場合は、以下の場所にあるはずです。

C:/Program Files/Epic Games/UE_《バージョン番号》/Engine/Content/Editor/Templates

対応 Template ファイルの特定

Templates ディレクトリの中から、カスタマイズしたいクラスに対応する Template ファイルがあるかどうかを調べます。存在しない場合、今回紹介する方法ではカスタマイズできません。

『Add C++ Class』ウィザードの Common Classes にて選択可能なクラスと、それらに対応する Template ファイルについて、以下の表にまとめました。

クラス名 (ウィザード内表記)継承元クラスTemplate ファイル名 (『*』= h, cpp)Template ファイルの流用元クラス
None(なし)EmptyClass.*.template-
CharacterACharacterCharacterClass.*.template-
PawnAPawnPawnClass.*.template-
ActorAActorActorClass.*.template-
Actor ComponentUActorComponentActorComponentClass.*.template-
Scene ComponentUSceneComponentActorComponentClass.*.templateUActorComponent
Player Camera ManagerAPlayerCameraManagerUObjectClass.*.templateUObject
Player ControllerAPlayerControllerUObjectClass.*.templateUObject
Game Mode BaseAGameModeBaseUObjectClass.*.templateUObject
World SettingsAWorldSettingsUObjectClass.*.templateUObject
HUDAHUDUObjectClass.*.templateUObject
Player StateAPlayerStateUObjectClass.*.templateUObject
Game State BaseAGameStateBaseUObjectClass.*.templateUObject
Blueprint Function LibraryUBlueprintFunctionLibraryUObjectClass.*.templateUObject
Slate WidgetSCompoundWidgetSlateWidget.*.template-
Slate Widget StyleFSlateWidgetStyle, USlateWidgetStyleContainerBaseSlateWidgetStyle.*.template-
Unreal InterfaceUInterfaceInterfaceClass.*.template-

「実は多くのクラスが専用の Template ファイルを持っておらず、UObject 用の Template ファイルを使ってコードの生成を行っている」ということがわかるかと思います。

つまり、今回紹介するカスタマイズ方法では、例えば「AHUD 継承クラスの自動生成コードのみを変更する」ということができません。何故ならば、AHUD 継承クラスのコード生成に使用している UObjectClass.*.template を編集すると、同じくこれらの Template ファイルを使用している他のクラスにも影響を与えてしまうからです。

もちろん、「UActorComponentUSceneComponent の両方に影響が出るのを承知の上で、ActorComponentClass.*.template を編集する」というのはアリです。

なお、クラスと Template ファイルとの対応関係は、/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp にて定義されている関数 FNewClassInfo::GetHeaderTemplateFilename() および FNewClassInfo::GetSourceTemplateFilename() の中身を読むとわかります。これらは「メンバ変数 BaseClass の型に対応する Template ファイル名を返す」関数であり、『Add C++ Class』ウィザードにて使用 Template ファイルを決定するために使用されています。

というか、このように「クラスと Template ファイルの対応関係が関数としてハードコーディングされている」のが、『② 対応する Template ファイルが存在しないクラスの場合、エンジンコードの修正とビルドが必要になる』原因だったりします。

Template マクロ

対応する Template ファイルを特定できた場合は、テキストエディタで編集します。

Template ファイルではマクロを使用することができます。Template マクロは、作成クラス名や継承元クラスなどに応じて、適切な文字列に置換されます。

Template マクロの一部を以下の表にまとめました。

マクロ説明置換後の例
%UNPREFIXED_CLASS_NAME%作成クラス名のプレフィックスなし版MyCharacter
%PREFIXED_CLASS_NAME%作成クラス名のプレフィックスあり版AMyCharacter
%BASE_CLASS_INCLUDE_DIRECTIVE%継承元クラスのヘッダファイルの #include ディレクティブ#include “GameFramework/Character.h”
%MY_HEADER_INCLUDE_DIRECTIVE%作成されるヘッダファイルの #include ディレクティブ#include “MyCharacter.h”
%MODULE_NAME%モジュール名ModuleName
%CLASS_MODULE_API_MACRO%モジュール API マクロ + 半角スペース
(ただし、ウィザードにて Class Type が Private に設定された場合は空)
MODULENAME_API
%COPYRIGHT_LINE%コピーライト文
(Project Settings の CopyrightNotice に設定されている文字列)
// Copyright HogeFuga, Inc. All Rights Reserved.

カスタマイズ時に多用しそうなマクロは %PREFIXED_CLASS_NAME% くらいだと思うので、表の内容をすべて覚える必要はありません。元々の Template ファイルに記述されているマクロの意味がわからない場合は、消さずにそのままにしておきましょう。

実例

実例というよりは動作確認に近いですが、AActor の Template ファイル内のコメント行をすべて削除して、『Add C++ Class』ウィザードで生成される AActor 継承クラスのコードに反映されるか確認してみます。

ActorClass.h.template と ActorClass.cpp.template を開き、メンバ関数に添えられているコメントをすべて削除します。

(.cpp の方だけ載せます)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
%COPYRIGHT_LINE%

%PCH_INCLUDE_DIRECTIVE%
%MY_HEADER_INCLUDE_DIRECTIVE%
%ADDITIONAL_INCLUDE_DIRECTIVES%

%PREFIXED_CLASS_NAME%::%PREFIXED_CLASS_NAME%()
{
    PrimaryActorTick.bCanEverTick = true;
}

void %PREFIXED_CLASS_NAME%::BeginPlay()
{
    Super::BeginPlay();
}

void %PREFIXED_CLASS_NAME%::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

%ADDITIONAL_MEMBER_DEFINITIONS%

その後、『Add C++ Class』ウィザードで AActor 継承クラス AMyActor を追加すると、MyActor.cpp は以下のように生成されました。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// Copyright HogeFuga, Inc. All Rights Reserved.


#include "MyActor.h"

AMyActor::AMyActor()
{
    PrimaryActorTick.bCanEverTick = true;
}

void AMyActor::BeginPlay()
{
    Super::BeginPlay();
}

void AMyActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

%COPYRIGHT_LINE% マクロで生成されたコピーライト文以外のコメントが出力されていないことを確認できました。

なお、Template ファイルは『Add C++ Class』ウィザードでコードを生成する段階で読み込まれるため、カスタマイズ後に Editor を再起動するなどの必要はありません。

余談ですが、Template 内のコメントは『Unreal Engine の開発者が Gameplay Framework の初学者へ宛てたヒント』という側面が強いため、個人的には慣れてきたら消してしまってよいものが多いかなと思っています。

(ノ゜∇゜)ノ<おわり

参考