Unreal EngineのC++プロジェクトを試してみる

2022-07-29

Unreal Engineのブループリントを使った簡単なサンプルの作り方はわかったので、C++も使えるようになろうと試してみた。

UEはプロジェクト作成時にブループリントとC++のどちらかを選択する必要がある。 ブループリントはビジュアルプログラミングができて、変更の反映も早いので使い勝手はいいんだけど、ちょっと大きいものを作ろうとした場合に備えてC++も使えるようになっておきたい。

環境編

プロジェクト作成

C++用のプロジェクトを作成すると、いきなりプロジェクトが動かない状態だった。 .NET Core 3.1をインストールする必要があるとのこと。 Visual Studio Community 2019から、「個別のコンポーネント」の「.NET Core 3.1ランタイム (LTS)」をチェックしてインストールする。

参考:Unreal Engine 4の.NET Framework SDKのエラーの解消方法 | やまだのログ

ホットリロードを無効にする

マシンのスペックによるのかわからないけど、C++のコードを変更してビルドするとものすごく時間がかかる。 まだテンプレートからプロジェクトを生成して、2・3個のソースしかないのにビルドに3分〜それ以上かかる。 デフォルトでホットリロードが有効になっていて、速くなりそうな機能だが自分の環境では逆に遅くなってしまうっぽい。

ホットリロードを無効にするには、

  • エディタの環境設定>一般>ライブコーディング>ライブコーディングの有効化」、または「コンパイルオプションメニュー(3つの点々アイコン)>ライブコーディングの有効化」のチェックを外す
  • 体感で、分単位でかかっていたものが、オフにすると10秒程度になる
    • でも遅いことも多い…
  • エディタ起動一発目は変わらず遅い…
  • 試しに再度有効にしてみるとビルドができなくなった:Unable to delete hot-reload file

プログラミング編

チュートリアル

右も左もわからないので、まずはチュートリアルを見るとよい:

クラスにつけるアトリビュート

UCLASS

UCLASS(config=Game)
class AFooBar: public ACharacter {
...

お約束

エディタからC++クラスを生成した場合には自動的に挿入されたコードになっているので問題ないが、念の為お約束。

作成したActorを継承するクラスは、ヘッダでgenerated.hをインクルードする:

...
#include "FooBar.generated.h"

そして、クラス定義では GENERATED_BODY() を先頭に記述する:

class AFooBar: public ACharacter {
GENERATED_BODY();

クラスのメンバにつけるアトリビュート

エディタのプロパティから設定できるようにしたいメンバにアトリビュートを指定する。

class AFooBar : Public ACharacter {
...
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ...)
class USpringArmComponent* CameraBoom;
...

Tickを実装

How can I properly override C++ Tick event in blueprint? - Unreal Engine / Programming & Scripting - Unreal Engine Forums

AActor クラスで定義されている Tick メソッドを自分のクラス内でオーバーライドし、実装する:

class AFooBar : Public ACharacter {
...
public:
virtual void Tick(float DeltaSeconds) override;

メソッド内では先頭で親クラスの Tick を呼び出してやる。

void AFooBar::Tick(float DeltaSeconds) {
Super::Tick(DeltaSeconds);
...

関係しそうなこと:

ログ出力

UE_LOG(LogTemp, Log, TEXT("Hello"));
  • カテゴリ名: LogTemp, …
  • Verbosity: ELogVerbosity::Type: Log, Warning, Error, Fatal, Verbose

FStringからTCHAR*への変換

デリファレンス(*)する:

FString s = ...;
UE_LOG(LogTemp, Log, TEXT("Hello: %s"), *s);

画面にテスト文字列出力(Blueprintのprint string相当)

GEngine->AddOnScreenDebugMessage(-1, 0.5f, FColor::Cyan, FString::Printf(TEXT("Tick: %.3f"), DeltaSeconds));

クラスの削除

  • コンテンツブラウザからは削除できない
  • VisualStudioなどから削除(ファイル自体も)
  • UnrealEngineを再起動
    • 残ってたらクリーン、リビルドが必要…

アクターのスポーン(生成)

試してみたがどうもうまくいかなかった…。

新規作成したGameModeBaseを使用しようとするとエラー

unreal c++ LogSpawn: Warning: Login failed: Failed to spawn player controller, GameSession is null

InitGame の頭で親クラスのメソッドを呼び出す必要がある:

void AMyGameModeBase::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage) {
AGameModeBase::InitGame(MapName, Options, ErrorMessage); // <= これを追加する

感想

  • ちょっと重すぎて開発にはキツい
  • なんかの拍子にプロジェクトを開こうとするとエラーが出てしまい、回復できなくなってしまうことがあった、ツラい
  • 様々な機能を使いこなすには、まだどの資料を見たらいいのかよくわかってない