PaperSloth’s diary

主にゲーム開発関連についての記事を書きます。

UE4 Logの収集について

環境

UE4.19.1


Logファイルの収集について

UE4でよく使うUE_LOGマクロ、PrintStringノードがありますね。

UE_LOG(LogTemp, Error, TEXT("Log message"));

f:id:PaperSloth:20180422183250p:plain

これらで出力したLogはSavedファイルに保存されます。
(ProjectDirectory)/Saved/Logs/(ProjectName).log

エラー処理をした時など、ログを探したい時などに役立ててください。

UE4 カスタムビルドエンジンの起動方法

環境

Unreal Engine (Git:4.19)
Visual Studio 2017 Community
Windows 10


Editorのexeについて

エンジンビルドの方法についてはヒストリアさんのブログが参考になります。
[UE4] エンジンのソースコード取得とビルド手順のまとめ UE4.6改訂版|株式会社ヒストリア


さて、カスタムビルドのエンジンを毎回IDEから起動するとどうしても時間がかかってしまいますね。

ですが、エンジンを一度ビルドすると実行ファイルが作られます。
(EngineDirectory)/Engine/Binaries/(Platform)/UE4Editor.exe


WindowsPCだと下記のフォルダに作成されます。
(EngineDirectory)/Engine/Binaries/Win64/UE4Editor.exe

実行するとLauncherからLaunchした際と同様です。
f:id:PaperSloth:20180422182325p:plain

UE4 IDEの変更方法

環境

UE4.19.1
Visual Studio 2017 Community


IDEの変更方法について

Unreal C++IDEMacではXCode, WindowsではVisual Studioを使用することが多いと思います。

IDEの変更方法はEditor PreferencesのSource Codeから変更します。
f:id:PaperSloth:20180422174833p:plain

Visual Studio 2017 Communityをインストールしたので、この機会に変更してみました。
f:id:PaperSloth:20180422175049p:plain

因みにこの後にOpen Visual Studio 2017を選択しても
プロジェクトをVisual Studio 2015で作成していたらVisual Studio 2015が開きます。
f:id:PaperSloth:20180422175229p:plain

Refresh Visual Studio 2017 Projectを選択してソリューションを更新します。
f:id:PaperSloth:20180422175351p:plain

これでプロジェクトでVisual Studio 2017を使用出来るようになります。
Visual Stuidio Code等他のIDEを使用したい場合もここから変更出来ます。

UE4 C++でGameModeの初期化を行う方法

環境

UE4.19.1
Visual Studio 2015 Community


GameModeで登録する初期値の初期化について

ここの部分の初期化についてです。
f:id:PaperSloth:20180422161755p:plain

C++で作成したGameModeBaseだと編集できないのですが
Blueprintだと楽に編集ができますね。
ここをC++側で編集する方法について書きます。

GameModeBaseに登録されているのは下記のような処理です。

AGameModeBase::AGameModeBase(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer.DoNotCreateDefaultSubobject(TEXT("Sprite")))
{
    // 省略

    DefaultPawnClass                     = ADefaultPawn::StaticClass();
    PlayerControllerClass                = APlayerController::StaticClass();
    PlayerStateClass                     = APlayerState::StaticClass();
    GameStateClass                       = AGameStateBase::StaticClass();
    HUDClass                             = AHUD::StaticClass();
    GameSessionClass                     = AGameSession::StaticClass();
    SpectatorClass                       = ASpectatorPawn::StaticClass();
    ReplaySpectatorPlayerControllerClass = APlayerController::StaticClass();
    ServerStatReplicatorClass            = AServerStatReplicator::StaticClass();
}

例えばGameModeBaseを継承したGameModeでnullptrを設定するとNoneになります。

AExampleGameModeBase::AExampleGameModeBase()
{
    DefaultPawnClass = nullptr;
}

f:id:PaperSloth:20180422163144p:plain

継承したクラスを登録したい場合は下記のようになります。

#include "ExampleGameModeBase.h"
#include "ExampleCharacter.h"
#include "ExamplePlayerController.h"

AExampleGameModeBase::AExampleGameModeBase()
{
    DefaultPawnClass      = AExampleCharacter::StaticClass();
    PlayerControllerClass = AExamplePlayerController::StaticClass();
}

f:id:PaperSloth:20180422170729p:plain

UE4 C++で複数実行ピンの作成

環境

UE4.19.1
Visual Studio 2015 Community


概要

いくつかやり方があって、今回は一番簡単でお手軽なenumを使ったやり方を紹介します。


enumを使った関数のおさらい

先ずは下記のようなenumを定義します。

UENUM(BlueprintType)
enum class EErrorCode : uint8
{
    Success,
    Failed
};

続いてUFUNCTIONマクロを使用してBlueprintに関数を公開します。

UFUNCTION(BlueprintCallable, Category = "Example")
void ExampleEnumInput(const EErrorCode ErrorCode);

// 関数内でErrorCodeの値が変わる関数を想定
UFUNCTION(BlueprintCallable, Category = "Example")
void ExampleEnumOutput(EErrorCode& ErrorCode);

constなしの参照にすることで引数が出力ピンに変わります。
constをつけた参照の場合は引数が入力ピンになります。

Blueprintから先程の関数を呼び出すと下図のようになります。
f:id:PaperSloth:20180422143212p:plain


enumを使った複数実行ピンの作成方法

さて、ようやく本題です。
enumを使って複数の実行ピンを使用するにはUFUNCTIONのmetaに下記を追加することで実現可能です。

UFUNCTION(/*省略*/,  meta = (ExpandEnumAsExecs = "ArgumentName"))

ArgumentNameの部分は任意の引数名を入力します。
実際に使用する引数名と一致するようにします。

先程の関数に手を加えて下記のように変更しました。

UFUNCTION(BlueprintCallable, Category = "Example", meta = (ExpandEnumAsExecs = "ErrorCode"))
void ExampleEnumMultiInput(const EErrorCode ErrorCode);
UFUNCTION(BlueprintCallable, Category = "Example", meta = (ExpandEnumAsExecs = "ErrorCode"))
void ExampleEnumMultiOutput(EErrorCode& ErrorCode);

Blueprint側から呼び出すと下記のようになります。
f:id:PaperSloth:20180422144216p:plain

enumで登録した値が全て実行ピンになっていますね。
後はC++側でswitchとかで処理を分けると良さそうです。

また、enumで定義を追加するとノードも変更されます。

UENUM(BlueprintType)
enum class EErrorCode : uint8
{
    None,
    Success,
    InternalError,
    ExternalError,
    NetworkError,
    UnknownError,
};

Noneを定義した場合は実行ピンには名前が出ません。
f:id:PaperSloth:20180422152849p:plain


簡単な応用

もう少し気の利いた処理になるように関数の中身も書いてみます。

Successの時、Failedの時でそれぞれ呼び出す関数を登録します。
C++だけで処理を実装するのは直ぐにできますが
今回はC++で関数の定義をしてBlueprintでロジックを実装する形にしてみましょう。

先ずは呼び出す関数の登録を行います。

UFUNCTION(BlueprintImplementableEvent, Category = "Example")
void OnSuccess();
UFUNCTION(BlueprintImplementableEvent, Category = "Example")
void OnFailed();

成功時、失敗時のそれぞれの関数を用意しました。
BlueprintImplementableEventはC++側で定義してBlueprintで関数のロジックを実装するときに使用します。
この定義だとBlueprintで処理の記述はできますが、関数呼び出しはC++からしか呼び出せません。
Blueprintからも呼び出したい場合は、BlueprintCallableと組み合わせることで使用できます。

複数実行ピンを入力できる関数で呼び出しを行うように処理を記述します。

void AExampleActor::ExampleEnumMultiInput(const EErrorCode ErrorCode)
{
    switch (ErrorCode)
    {
        case EErrorCode::Success:
            OnSuccess();
            break;
        case EErrorCode::Failed:
            OnFailed();
            break;
    }
}

これでBlueprint側で処理の登録と呼び出しを行ってみましょう。
下図のように組むとSuccessに実行ピンを繋ぐとOnSuccessが呼ばれ
Failedに実行ピンを繋ぐとOnFailedが呼びだされます。
f:id:PaperSloth:20180422150809p:plain

こういった処理を書く場合はDelegateで登録することが多いですが
今回は複数実行ピンを使用したイメージとして用意してみました。


また、余談ですがMultiOutput関数は
下図のようにOutputをSwitch分岐させるのと同様の処理になります。
ですが、C++側で何か処理を加えたい場合に役立ちますし、ノードもスッキリするため
ExpandEnumAsExecs を積極的に使用した方が良いでしょう。
f:id:PaperSloth:20180422151304p:plain

UE4 SpawnActorDeferredについて

環境

UE4.19.0
Visual Studio Community 2015

SpawnActorについて

SpawnActorを呼び出すにはWorld, 生成位置、回転情報、名前や所有者の登録等のオプションが必要になります。

#include "Engine/World.h"
#include "ExampleActor.h"

void AExampleGameMode::BeginPlay()
{
    Super::BeginPlay();

    auto const World = GetWorld();
    const FTransform SpawnTransform = FTransform::Identity;
    FActorSpawnParameters parameters;
    auto const exampleActor = World->SpawnActor<AExampleActor>(AExampleActor::StaticClass(), SpawnTransform, parameters);
}

基本的にはこれで問題ないのですが
BeginPlayが呼び出される前に処理を行いたい場合や値を渡したいという場合もあります。

そんな場合に役立つのがSpawnActorDeferredです。

SpawnActorDeferredについて

一先ずコードから見ていきましょう。

#include "Engine/World.h"
#include "ExampleActor.h"

void AExampleGameMode::BeginPlay()
{
    Super::BeginPlay();

    auto const World = GetWorld();
    const FTransform SpawnTransform = FTransform::Identity;
    auto const exampleActor = World->SpawnActorDeferred<AExampleActor>(AExampleActor::StaticClass(), SpawnTransform);

    // BeginPlayが呼び出される前に処理したい初期化処理等
    exampleActor->Initialize();

    // ここでBeginPlayが呼び出される
    exampleActor->FinishSpawning(SpawnTransform);
}

SpawnActorDeferredを利用する機会は何かしら作っていると何度も出てきます。
頭の片隅に入れておくと便利です。

UE4 C++でのExposeOnSpawnについて

環境

UE4.19.0
Visual Studio Community 2015

Expose On Spawnとは

Spawn Actor from ClassでActorをSpawnする際に初期化できる変数のことです。
f:id:PaperSloth:20180413230104p:plain

Blueprintで設定する際は下図のように設定を行います。
f:id:PaperSloth:20180413230236p:plain

Expose on Spawnにチェックを入れるのはもちろんですが
Instance Editableにもチェックを入れる必要があります。

チェックを忘れた場合はコンパイル時に警告となります。


さて、これをC++側で定義する方法についてです。

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Game", meta = (ExposeOnSpawn = true))
    float ExampleExposeValue;

このようにmetaにExposeOnSpawnと書くだけでSpawn時に値を割り当てることができます。
f:id:PaperSloth:20180413232056p:plain

    meta = (AllowPrivateAccess = "true")

このようにmeta指定子の種類によってはtrueを文字列として囲うものもあるので、ちょっとした注意が必要です。

また、C++側で生成時に値を割り当てる時はSpawnActorDeferredを使用しますが、それはまた別の機会に紹介させていただきます。
SpawnActorDeferredについて書きました。
こちらも合わせて読んでおくと便利です。
papersloth.hatenablog.com