UE4 C++ビルドエラー対応覚書

この記事は何?

この記事はUnreal Engine 4 Advent Calender 2019その2の6日目の記事です。

qiita.com

UE4 C++でのコンパイルビルド時のエラーの対応メモです。 慣れればエラーを見てどんな問題が起こっているのかわかるのですが、慣れていないと原因がわかりづらいです。

そんなエラー文からどのような対応をすればよいのかのメモになります。

2020/01/14:少し追記しました。

クラス名.cpp(1): error : Expected クラス名.h to be first header included.

UCLASSのcppはクラス名.hを最初にインクルードしないといけないというエラー。 最初のインクルード(#include するファイル)をクラス名のものに変更する。 (このファイルに使うクラス名は、接頭詞U,F,A,Iなどを外したものです)

#include "クラス名.h"

関数名 inconsistent dll linkage

なんとか_APIがそのクラス, 関数, 変数を定義したモジュールとあってない。コピペしたときとかにクラス名だけしか変更してなくて起こりがち。

class MYMODULE_API UMyActor : public AActor
//    ^^^^^^^^^^^^
//     ここに注目
//
// この場合、MyModuleというモジュール名(プラグイン名)の中で定義されていないといけない

~関数が未定義 error LNK2019: unresolved external symbol 関数名

関数の実装が見つからないエラー。

Build.csに必要なモジュールがDependencyに追加されていない。 Build.cs以外にuprojectのAdditionalDependenciesに追加されているパターンもあるので、他のプロジェクトから移植する際にはBuild.cs以外にも.uprojectの設定も気をつける。

または定義されていない関数がどこかで呼ばれている可能性もあり。(他のプロジェクトからコピペしたときや、外部公開されていない関数などを呼んでしまった場合に上記とエラー理由と勘違いして起こりがち?)

解決策の例:

PrivateDependencyModuleNames.AddRange(
new string[]
{
 "UnrealEd",
  "LevelEditor",
  "CoreUObject",
  "Engine",
  "Slate",
  "SlateCore",
// こういうところに指定の関数が定義されているモジュール、プラグインを追加する

関数名の前にあるクラス名をUE4APIリファレンス(Unreal Engine API Reference | Unreal Engine Documentation)で検索して、そのクラスのReferencesのModuleに書いてあるモジュール名を追加するとだいたい解決すると思います。

error LNK2019: unresolved external symbol "declspec(dllimport) private: static class UClass * cdecl クラス名::GetPrivateStaticClass(void)

 Privateなクラスを使おうとしたときに出るエラー。(Privateフォルダ以下にあるファイルで定義されているUCLASS) もしくは、Publicであっても外部モジュールの_APIが無いクラスを使おうとしたときとか、DependencyModule足りない場合でも起こる。

その対象のクラスはアクセス権がないので、Privateフォルダにある場合、編集できる領域ならPublicフォルダに移動したり、Publicアクセス権で出たならなんとか_APIを追加する、編集できない場合には他の代替クラスを使用しましょう。 エンジン内にあるクラスのときには、クラス丸ごとコピーして自身のプロジェクトで使う方法もあります。それで使うことが可能ならエンジン改造せずに済むので有効です。

UnrealBuildTool : error : Expecting to find a type to be declared in a module rules named 'モジュールA名' in モジュールB名ModuleRules, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null. This type must derive from the 'ModuleRules' type defined by Unreal Build Tool.

Build.csのModuleRuleを継承しているクラス名がModuleA名と同じではない……ときに出たエラー。あまり見たことはないのでそういう制限によるエラーではないかもです。(IMPLEMENT_MODULEの名前とクラス名が違うからかも?) UnrealBuildToolではクラス名とModule名を同じにする必要がある。

class FMyModule : public ModuleRule
// この場合、MyModuleというモジュール名でないといけない

もしくは、Target.csに追加しているモジュール名が、存在しないモジュール名になっているのが原因かも?

.gen.cpp(23): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

37>.gen.cpp(23): error C2146: syntax error: missing ';' before identifier 'UClass'
37>.gen.cpp(110): error C2065: 'Z_Construct_UClass_クラス名_NoRegister': undeclared identifier
37>.gen.cpp(151): error C2065: 'Z_Construct_UClass_クラス名_NoRegister': undeclared identifier

コンパイラが型を理解していない。

たとえばクラス名がALevelSequenceActorだった場合、エラーの行数に飛ぶと、 LEVELSEQUENCE_API UClass* Z_Construct_UClass_ALevelSequenceActor_NoRegister(); となっています。 なので、LEVELSEQUENCE_APIの対象モジュールをPublicDependencyやPrivateDependencyに追加して解決します。対象モジュールというのが、今回の例だとLevelSequenceモジュールです。

PublicDependencyModuleNames.AddRange(new string[] { "LevelSequence" });

Please verify that you have sufficient rights to run this command.

VisualStudioをアップデートしたときに起こったエラー。 プリコンパイルヘッダーとかがアップデート前のコンパイラコンパイルしたものが残っていたりして失敗しているみたいです。

リビルドすると治ります。

UnrealBuildTool : error : Unhandled exception: System.IO.DirectoryNotFoundException: パス '\Plugins\HogeHogePlugin\Intermediate\Build\Win64\UE4Editor\Inc\HogeHoge' の一部が見つかりませんでした。

プラグインの中にgenerated.h されるクラスが1つも存在しなくてIncフォルダ内のコード生成が通らなかったため、フォルダが見つからずエラーになってます。 なにか1つUCLASSかUSTRUCTを対象プラグインのコード内で作成して、GENERATED_BODYされるようにしてみましょう。

HogeHoge.generated.h(16): error C2007: #define syntax

#define syntax がたくさん出たときの対処法。対象の行に飛んでみると、なんとかRPC_WRAPPERSやらなんとかINCLASS_NO_PURE_DECLSの部分に飛びます。 これは、フォルダ名の先頭に数字がついているものを使っていると、#defineの定義が失敗してビルドエラーになってしまいます。uprojectを入れているフォルダ名を、数字を先頭にしないか、英字のみにしてみましょう。 (おそらく日本語フォルダ名でも同じエラーが出る)

終わりに

UE4独自の守らなくてはいけないこと、対処法などは調べて対応していくうちに理解していけると思います。 頑張って覚えて楽しいUE4 C++ライフを過ごしましょう。(宣伝:同人誌でUnreal C++本とボイチェン本書いているのでよければどうぞ

明日はNaotsunさんの「自作ブレンドアニメーションノードを作る」です。よろしくお願いします。

UE4のVisualStudioソリューションファイルの作り方について

UE4プロジェクトのVisualStudioソリューションファイルの作り方について

どこがどう繋がって、どのエンジンバージョンのソリューションが作成されるのか理解していなかったので、まとめました。 あくまでUE4でのVSソリューションファイルの作り方についてなので、UE4プロジェクトのバージョンコントロール方法ではありません。そのような情報がほしい場合には、ソース コントロールとして SVN を使用する | Unreal Engineなどを参考にしましょう。

ちなみにVer4.19ぐらいのときにメモしたやつなので、最新だと変わっていたりするかもしれません。

YOUR_PROJECT という部分は、自身の作成したプロジェクト名に置き換えてください。 方法はパターンA、パターンBみたいに列挙していきますので、お好きな手段を選ぶとよいです。

【エンジンソースの取得方法】

  • A. GithubからCloneして取得(お好きな作業フォルダへどうぞ)
  • B. EpicGamesLauncherからInstallOption->エンジンソースにチェック (デフォルトパス設定は、 [C:\Program Files\Epic Games\UE_4.xx\Engine])

【ソリューションファイルの作成方法】

  • A. Editor起動して、メニューの[File]->[Generate Visual Studio Project]、もしくは[File]->[RefreshProjects]
  • B. Setup.batと同階層に存在する、[GenerateProjectFiles.bat]を実行
  • C. YOUR_PROJECT.uprojectを右クリック->[Generate Visual Studio project files]
  • D. VisualStudioExtensionを入れておき、VisualStudioのツールバーから[Refresh Projects]ボタンを押す

【非改造・改造別 作成例】

リリースされているエンジンを使用したC++開発(非改造エンジン)

  • A. EpicGamesLauncherからEditorを起動、YOUR_PROJECT.uprojectをEditorで開き、メニューの[File]->[RefreshProjects]
  • B. YOUR_PROJECT.uprojectを右クリック->[Open]でEditorを開く->メニューの[File]->[Refresh Projects]
  • C. YOUR_PROJECT.uprojectを右クリック->[Generate Visual Studio project files]
  • D. YOUR_PROJECT.slnをVisualStudioで開き、VisualStudioのツールバーから[Refresh Projects]ボタンを押す(要:VisualStudioExtension)

改造エンジンを使用したC++開発

  • A. 改造エンジンと同階層にそのエンジンで開発するプロジェクトのフォルダを入れ、さらに同階層にGenerateProjectFiles.batがある形にする
例:
  MyUE4Engine/Engine/ (エンジンソース)
  MyUE4Engine/YOUR_PROJECT/ 
  MyUE4Engine/GenerateProjectFiles.bat

 MyUE4Engine/GenerateProjectFiles.batでソリューションファイルを作成する。 また、.uprojectのEngineAssociation項目は空にしておく。 "EngineAssociation": "", こうすることで、なぜかYOUR_PROJECTの上の階層にあるEngineフォルダ内のUE4をエンジンとして使ってくれるらしい。

(設定参考: https://github.com/EpicGames/UnrealTournament

  • B. 改造エンジンのEditor起動、YOUR_PROJECT.uprojectをEditorで開き、メニューの[File]->[Refresh Projects]
  • C. YOUR_PROJECT.slnをVisualStudioで開き、VisualStudioのツールバーから[Refresh Projects]ボタンを押す(要:VisualStudioExtension)

補足

Aの方法だと、MyUE4Engine/UE4.slnが作られるので、それを開きます。 BとCの方法だと、開くのはUE4.slnではなく、YOUR_PROJECT.slnになって、パスはMyUE4Engine/YOUR_PROJECT/YOUR_PROJECT.slnになると思います。

おすすめの方法は?

非改造 -> どれでもやりやすい方法でいいと思います。

改造 -> AのGenerateProjectFiles.batを使用したもの。同じフォルダにまとまっていることで管理しやすくなり、uprojectのEngineAssociationを空白で管理できるので、環境によってEngineAssociationが異なるハッシュタグになってuprojectファイルに差分が出てしまう問題を防げる。

例:改造エンジンでゲームを作ってみたい(Windows環境)

Engineソースをダウンロードする。develop/MyUE4GameパスにてGitからCloneした。

develop/MyUE4Game/Engine/
develop/MyUE4Game/Samples/
develop/MyUE4Game/Templates/
develop/MyUE4Game/Setup.bat
develop/MyUE4Game/GenerateProjectFiles.bat
develop/MyUE4Game/README.md

Setup.batで必要なものをインストール。 GenerateProjectFiles.batでエンジン用ソリューションUE4.slnを作成。

develop/MyUE4Game/Engine/
develop/MyUE4Game/Samples/
develop/MyUE4Game/Templates/
develop/MyUE4Game/Setup.bat
develop/MyUE4Game/GenerateProjectFiles.bat
develop/MyUE4Game/README.md
develop/MyUE4Game/UE4.sln <- New!

エンジンをビルドしてEditor起動。 テンプレートからC++プロジェクトを作成する。作成パスはdevelop/MyUE4Gameにして、プロジェクト名はFPSGameとする。

develop/MyUE4Game/Engine/
develop/MyUE4Game/Samples/
develop/MyUE4Game/Templates/
develop/MyUE4Game/FPSGame/ <- New!
  develop/MyUE4Game/FPSGame/FPSGame.uproject <- New!
develop/MyUE4Game/Setup.bat
develop/MyUE4Game/GenerateProjectFiles.bat
develop/MyUE4Game/README.md
develop/MyUE4Game/UE4.sln

develop/MyUE4Game/UE4.slnを開くと、FPSGameソリューションが含まれているので、それをUE4.slnのスタートアッププロジェクトにすれば完成。 (出来ていなかったらGenerateProjectFiles.batで再作成する)

エンジンいじらない状態でゲーム部分だけ開発するときには、develop/MyUE4Game/FPSGame/FPSGame.slnを開いてビルドして実行でもよいとかそんな感じだったと思います。(多分)

トラブルシューティング

UE4のVisualStudioExtensionってどこにあるの?

エンジンコードフォルダの、Engine\Extras\UnrealVSにあります。 (詳細: https://docs.unrealengine.com/latest/JPN/Programming/Development/VisualStudioSetup/UnrealVS/index.html

.uprojectを右クリックでUnrealのメニューが出てこない

EpicGamesLauncherと拡張子の関係付けができていない。 EpicGamesLauncherを起動して開くと、復旧するか聞かれるので復旧してください。

VisualStudioのツールバーの[Refresh Projects]がグレーアイコンで押せない

同上?使っていないので条件は詳しく調べていません……とりあえず次のを試してみてはいかがでしょうか?

EpicGamesLauncherと拡張子の関係付けができていないため?EpicGamesLauncherを起動して開くと、復旧するか聞かれるので復旧してみてください。 もしくは、GenerateProjectFiles.batがソリューションファイルと同じフォルダにないから? 改造エンジンだと非対応?

.uprojectで生成されるエンジンコードのバージョンが決まる基準は何なの?

 .uprojectの"EngineAssociation": の値で決まる。.uprojectをテキストファイルとして開くと書いてあります。

  • 単純な数値 -> エンジンのバージョン(Epic Games Launcherのエンジンを使用する)
  • ハッシュ値 -> PC固有のパスがレジストリに登録されていて、それが基準になる
  • 空欄 -> 親フォルダにエンジンフォルダがあればそれを使用する。無ければバージョン指定をGUIで設定する必要がある

 参考: http://historia.co.jp/archives/2316/

GenerateProjectFiles.batが見当たりません

非改造エンジン(Launcherからダウンロードしたエンジン)には存在しません。 代わりにuprojectファイルを右クリックして、[Generate Visual Studio project files]からslnなどのファイルを更新しましょう。

VisualStudio2017のソリューション作りたいのに2015のが作られてしまう

対応しているエンジンバージョンの場合、GenerateProjectFiles.batのコマンドライン引数に -2017 を加えると作ってくれます。 2019でも同じだと思います。

$ ./GenerateProjectFiles.bat -2017

技術書典4で頒布したUE4 C++ 同人誌の電子版を販売開始しました

Twitterのみでしか宣伝しておりませんでしたので、こちらでも宣伝します。 技術書典4にて物理本で頒布したUnreal C++本のPDF電子版の販売をBoothにて行っております。 本文132ページ、1200円です。

booth.pm

(紹介文より抜粋) UE4でゲーム開発をしようとするときに、どうやってUnreal C++メインで実装していくのかをステップバイステップで解説します。UE4のバージョンは4.19で動作確認しております。(物理本を初頒布時の最新版です)

コンポーネントの追加、アクター生成、当たり判定、デリゲート、入力、UI(UMG)などゲーム制作における基本を作る方法を、簡単なシューティングゲームを題材に詰め込みました。 ※必要な機能を可能な限りUnrealC++で実装してみるという内容であり、ゲームは完成しませんのでご注意ください。

ObjectInitializer.CreateDefaultSubobject、ConstructorHelpers::FObjectFinder、ConstructorHelpers::FClassFinder、TSubclassOf、CODなど気になる単語がありましたら読んでみると役に立つかもしれません。 タイトルが悪かったのか、『UnrealC++ 本』だったり、『UE4 C++ 本』とかで検索しても出てこなかったので、これで少しググラビリティ上がるといいなと思いつつ宣伝エントリを書きました。 もしご興味があればご購入していただけると増補改訂版や続編とか、UE4関連同人誌が今後出るかもしれません。

よろしくお願いしますー。

f:id:finap:20190223101801p:plain