PaperSloth’s diary

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

UE4 個人開発メモ

最終更新日:2017/12/03

概要

 個人開発でのUE4のEditor Preference, Project Settings等のメモ
 随時更新していきます。
 基本はWindowsPC向けの内容。
 家庭用ゲーム機、アーケードゲーム、モバイル、XR(AR / VR)でも役立つ内容も含みます。
 各項目には確認時のバージョンを記載しています。
 バージョンが古かったり新しかったりすると
 項目がなくなったり、場所や名前が変わったりしている可能性があります。

環境

・Platform : Windows
・Unreal Engine4.17.2~
Visual Studio Community 2015


Project Settings

Windowタイトルの変更方法(UE4.17.2)

 WindowタイトルとはPC向けに作成した際のWidnowの左上に出るタイトルです。
f:id:PaperSloth:20171130003303p:plain

 何も指定していない場合はProject名が表示されます。

 設定は下図のProject - Description - Displayed
 「Project Displayed Title」から変更できます。
f:id:PaperSloth:20171130004532p:plain

 試しに"Example Window Name"と入れてみました。
f:id:PaperSloth:20171130004635p:plain

Application名の変更方法(UE4.17.2)

 上記Windowsタイトルとよく間違えやすいのがこれです。
 設定は下図のProject - Description - About
 「Project Name」から変更できます。
 デフォルトではUE4Gameと入っています。
f:id:PaperSloth:20171130005438p:plain

 よくWindowタイトルを変更しようとしますが、ここを変えても上手くいきません。
 この名前はタスクマネージャー等で表示されるアプリの名前です。
f:id:PaperSloth:20171130005618p:plain

 ちょっと図がわかりにくいのですがProject Nameがあって、その下にWindowTitleがくるようになっています。
 編集をしていない場合だと、UE4Gameの下にProject名がくるようになっています。
f:id:PaperSloth:20171130010129p:plain

シェーダーモデルの制限によるメモリ容量削減(UE4.17.2)

 設定は下図のPlatforms - Windows
 「Targeted RHIs」から変更できます。

 UE4Windows向けに作成している場合
 デフォルトのRHI(Rendering Hardward Interface)はDX10, DX11が有効になっています。
f:id:PaperSloth:20171130220108p:plain
 これをDX11(ShaderModel5)のみにすることで不要なシェーダーが減り、パッケージ容量を削減できます。
 ThirdPersonTemplate等で試してみてもほぼ全く変わらないのですが
 規模が大きく、マテリアルが増えるほど効果が現れやすい部分です。

 試しに自分のゲームで比較してみた結果
 DX10, 11だと242KBのシェーダー
f:id:PaperSloth:20171130221048p:plain
 DX11のみだと124KBと約半分の容量になりました。
f:id:PaperSloth:20171130221057p:plain

 このように数百KB程度だと微々たる差ですが、これが数百、数千のマテリアルとなると話が変わってきます。
 また、シェーダーも1つで数百MBだと半分ほどの容量になるのは大きな変化ですね。

パッケージング関連

 項目が多いので、細かく分けます。
 設定箇所はProject - Packaging以下のものになります。

PakFileの使用(UE4.17.2)

 「Use Pak File」にチェックを入れると有効になります。
 説明の前に図で見てもらうと分かりやすいと思います。
 Pak Fileを使用した場合
f:id:PaperSloth:20171130222234p:plain
 中には.pakの形式でContent以下のAssetが1つのデータに圧縮されています。

 Pak Fileを使用しない場合
f:id:PaperSloth:20171130222333p:plain

 Pakファイルの使用は容量の削減になり
 転送ファイル数が減るので配布時のダウンロードも早くなり
 ロードも早くなるため使用することを推奨します。
 容量の参考までに自分のプロジェクトで使用した場合の容量を載せておきます。
 使用した場合  :532MB
 使用しない場合 :786MB

パッケージの圧縮(4.17.2)

 「Create compressed cooked packages」にチェックを入れると有効になります。
 f:id:PaperSloth:20171203220605p:plain
 なお、このオプションの効果を有効にするにはUse Pak Fileにチェックを入れておく必要があります。
 容量の参考までに自分のプロジェクトで使用した場合の容量を載せておきます。
 使用した場合  :547MB
 使用しない場合 :950MB

 さて、パッケージの圧縮はDLで配信するPC向け等にはオススメですが、
 一部プラットフォームは注意が必要です。
 PlayStation 4の場合
  PlayStation 4 の圧縮と重複し、ファイル サイズは減らずにロード時間が長くなってしまいます。
 Nintendo Switchの場合
  ロード時間が早くなる場合と遅くなる場合があります。
 詳しくは下部の参考資料のリンクを見てください。


Editor Preference

Blutilityの有効化(UE4.17.2)

 BlutilitはBlueprintをEditor上で呼び出すことでお手軽にEditor拡張が出来る機能です。
 UE4.17.2現在は実験的な機能として提供されています。
 この機能に関しては不安定というよりは、機能がまだ足りないため実験的な機能なのだと思います。

 設定は下図のEditor Preference - General - Experimental - Tools
 「Editor Utility Blueprints(Blutility)」から有効に出来ます。
 有効にした際のEditorの再起動は不要です。
f:id:PaperSloth:20171130011354p:plain

EQS(Environment Querying System)の有効化(UE4.17.2)

 EQSはAIが目的に応じた位置を探す時に使われる機能です。
 この位置は動的に生成され、その中から最もスコアの高い位置を選択します。

 こちらも実験的な機能として提供されていますが
 EpicGamesの開発タイトルである「Robo Recall」でも採用されており、信頼性は高いです。

 設定は下図のEditor Preference - General - Experimental - AI
 「Environment Querying System」から有効に出来ます。
 有効にした際のEditorの再起動は不要です。
f:id:PaperSloth:20171130012353p:plain

参考資料

シェーダーモデルの制限によるメモリ容量削減
バイキング様のスライド63ページ付近に該当箇所の説明があります。
マジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DD

パッケージング関連
パッケージの圧縮によるプラットフォームごとの注意点等詳しくはドキュメントに載っています。
Unreal Engine | プロジェクトのパッケージ化

Poem WinMainとプロジェクト設定

環境

Visual Studio 2015 Community
C/C++(C++11)
SVN


概要

タイトルにもありますが、ポエムです。
革新的な技術も新しい事柄も特にありません。

「エンジンに頼らず
一からプログラミングしてるんだぁ~」
ということで、オレオレエンジンを作り始めます。

環境にも書きましたがC/C++(C++11)です。
C++14, 17も取り入れていければいいですが、一先ずはC++11で。
C言語も残っているので、それは今後消していきます。


プロジェクト作成

一先ずはWinMainでも書いておきます。

#include <Windows.h>

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR lpCmdLine, int nCmdShow)
{
	return 0;
}

何もしないを実行するプログラミングの完成です!


プロジェクト設定

自分の使いやすいように設定を色々と変えていきます。

文字セットはいつものマルチバイト

ターゲットプラットフォームはWindows10が幾つかあって、どれがいいんでしょうね。
ここでは10.0.14393.0にしました。

出力ディレクトリと中間ディレクトリも変更しています。
大体binとobjって名前にしています。
f:id:PaperSloth:20180214232937p:plain

あとは警告レベルの設定だけ変更しておきます。
f:id:PaperSloth:20180214233238p:plain

この辺はDebugとReleaseの両方で同じ設定にしています。
他にもやっておいたほうがいいことは山ほどありますが、一先ずこれで始めることにします。

UE4 マウスカーソルを自作アイコンにする

環境

Unreal Engine 4.18.3


マウス座標の取得

Widgetでマウス座標を取得するには下記の2つのノードがあります。
・Get Mouse Position
・Get Mouse Position Scaled by DPI
f:id:PaperSloth:20180206195202p:plain

基本的にはGet Mouse Position Scaled by DPIで良いです。

画面解像度が固定でDPIスケールが1.0の場合や
DPIスケールの値が変わらないようにしている場合など
特殊な場合はGet Mouse Positionを使う場合もあると思います。

DPIスケールは画面解像度の変更に合わせてUIのサイズを変更してくれる機能です。
例えば、DPI Scaleが1.0の場合はGet Mouse Positionで問題ありませんが
初期設定では1280x720でWidgetを編集しており、DPI Scaleは約0.66です。
この値はProjectSettings -> Engine -> User Interfaceからカーブエディタで自由に編集できますが
基本的には初期設定のまま開発を行うでしょう。
初期値は1920x1080では1.0で3840x2160の場合は2.0が設定されています。
f:id:PaperSloth:20180206195021p:plain

この辺りの解像度の変化の違いをユーザー側が気にせず取得できるのが
Get Mouse Position Scaled by DPIとなっています。


マウスカーソルの変更

今回はマウスカーソルのみのWidget(WBP_MouseCursor)と
それを使用するWidget(WBP_MouseMove)の2つのWidgetを用意します。
f:id:PaperSloth:20180206195421p:plain

マウスカーソルのみのWidgetは下記のようにImageを1つ置いただけのWidget
Blueprint Graphには特に変更を加えません。
今回は特に素材を用意していないので、ポイントライトのテクスチャを使用しています。
f:id:PaperSloth:20180206195342p:plain

因みにマウスカーソルのみのWidget(WBP_MouseCursor)を作成してパーツとして分けていますが
今回の実装内容的にはWBP_MouseMoveにImageを配置する実装でも問題ありません。

もう一つのWidget(WBP_MouseMove)には先ほど作成したWidgetを配置します。
Palette内にUser Created -> WBP_MouseCursor(自作Widget名)があることを確認します。
f:id:PaperSloth:20180206195740p:plain

今回はマウスカーソルのアイコンがマウスの中心にきてほしいため
Allignmentには0.5. 0.5を代入してマウスカーソルの中心にアイコンがくるように補正しています。
f:id:PaperSloth:20180206195918p:plain
座標は画面外でもどこでもお好きなように。

続いてBlueprintの実装に移ります。
一旦は作成したWidgetを描画します。
ここでは確認のためにLevel Blueprintで行っています。
f:id:PaperSloth:20180206200024p:plain

続いて先ほど作成したWidgetのBlueprint Graphに移ります。
先ずは動作確認用に一旦マウスカーソルを表示することにします。
f:id:PaperSloth:20180206200141p:plain

ここまでで実行してアイコン画像とマウスカーソルが表示されていることを確認します。
f:id:PaperSloth:20180206200508p:plain


マウスカーソルの追従

マウスカーソルの座標を更新するには
アイコンの座標にMouse座標を代入するだけですね。

下記のようなノードになります。
f:id:PaperSloth:20180206200828p:plain

実行すると下記のようにアイコンがマウスの位置に合わせて動くことが確認できます。
※キャプチャーツールの都合上、マウスカーソルは表示されていません。


続いてマウスカーソルの位置に徐々に近づくような実装も紹介しておきます。
Interp Toノードで徐々に値を更新することで実現可能です。
f:id:PaperSloth:20180206201540p:plain

動画が分かりにくいのですが、実行してみるとこんな感じです。

今回は適当に5という値を入れましたが
変数に昇格させて場面によって速度を変えたりオプション画面から変更できると便利そうですね。

最後に動作確認ができたので、不要であればShow Mouse Cursorを削除しておきます。
以上で完成です。

UE4 リフレクションに指定できる型について

環境

Unreal Engine 4.17.2

概要

Blueprintに公開可能な型と公開できない型を書いていきます。
他にも追記した方がいいことがあれば、コメントやTwitterで指摘いただけると助かります。
UPROPERTYで説明していますが、UFUNCTIONでも基本的に同様です。

enumUENUMを付ければ公開可能です。
structはUSTRUCTを付けてBlueprintTypeが指定されていれば公開可能です。

コードは下記クラスに追加していきます。
因みにUPROPERTYでCategoryを指定しない場合はクラス名がカテゴリ名になります。

#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ReflectionActor.generated.h"
 
UCLASS()
class PROJECTNAME_API AReflectionActor : public AActor
{
    GENERATED_BODY()
public:
    AReflectionActor();
private:
    // ここに変数を追加
};



Blueprintに公開可能な型

公開可能なプリミティブ型

UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
bool _bool;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
uint8 _uint;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
int32 _int;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
float _float;

f:id:PaperSloth:20180131234057p:plain


公開可能なUE4の型

ここではよく使う型だけを紹介します。
他にも挙げきれないくらい種類があります。
一部の構造体とUObjectを継承しているクラスポインタが公開可能です。

UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
FName name;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
FString string;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
FText text;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
FVector vector;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
FRotator rotator;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
FTransform transform;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
UObject* _object;

f:id:PaperSloth:20180131234302p:plain

UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
FMatrix matrix;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
FQuat quat;

Matrix, QuaternionはBlueprintへの公開は可能です。
f:id:PaperSloth:20180201005332p:plain
ですが、これらを操作するための関数はBlueprintにはほとんど公開されていません。

公開可能な構造体、列挙型

USTRUCT(BlueprintType)
struct FFoo
{
    GENERATED_USTRUCT_BODY()
 
    float _float;
 
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    int32 _int;
};
 
// 省略
 
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
FFoo foo;


この場合はUPROPERTYを公開設定で付与した_intのみがBlueprint上に公開されます。
f:id:PaperSloth:20180201005640p:plain

UENUM()
enum class EBar : uint8
{
    State1,
    State2,
    State3,
    Num        UMETA(Hidden)
};
 
UENUM()
namespace EBaz
{
    enum Type
    {
        State1,
        State2,
        State3,
        Num        UMETA(Hidden)
    };
}
 
// 省略
 
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
EBar bar;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
TEnumAsByte<EBaz::Type> baz;


enumの書き方を2種類紹介しましたが、Blueprintからの見え方は同じです。
f:id:PaperSloth:20180201005828p:plain
EBazのような古いenumの書き方を示したのには理由があります。
UE4のエンジンコードにはまだ古い書き方が残っているため
それらを利用する際にTEnumAsByteを使用します。
自身で列挙型を定義する際は上のEBarのような書き方をオススメします。
詳しくはこちら
papersloth.hatenablog.com

公開可能なcontainer

UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
TArray<int32> _array;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
TMap<int32, int32> map;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
TSet<int32> set;

ここではintを指定していますが
公開可能なプリミティブ型、構造体、クラスポインタは基本的に使用可能です。
f:id:PaperSloth:20180201010039p:plain

また、Map, SetのBlueprintでの扱いに関してですが
4.13以下では使用不可
4.14では実験的な機能
4.15から正式なサポートとなります。


Blueprintに公開不可能な型

これらはC++側では当然使用可能ですが、Blueprintへの公開はできません。
UPROPERTY, UFUNCTIONを付与するとエラーとなります。
Blueprintで使用したい場合はcastするなどの対応が必要です。
数が多いため、一部のみを抜粋しています。

プリミティブ型

UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
uint16 _uint16;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
uint32 _uint32;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
uint64 _uint64;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
int8 _int8;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
int16 _int16;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
int64 _int64;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
double _double;


UE4で定義された型、container

#include "Containers/StaticArray.h"
 
// 省略
 
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
FMatrix2x2 mat22;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
TStaticArray<int32, 10> staticArray;



コード全容

// Copyright(c) 2018 PaperSloth

#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Containers/StaticArray.h"
#include "ReflectionActor.generated.h"
 
USTRUCT(BlueprintType)
struct FFoo
{
    GENERATED_USTRUCT_BODY()
 
    float _float;
 
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    int32 _int;
};
 
UENUM()
enum class EBar : uint8
{
    State1,
    State2,
    State3,
    Num        UMETA(Hidden)
};
 
UENUM()
namespace EBaz
{
    enum Type
    {
        State1,
        State2,
        State3,
        Num        UMETA(Hidden)
    };
}
 
UCLASS()
class PROJECTNAME_API AReflectionActor : public AActor
{
    GENERATED_BODY()
public:
    AReflectionActor();
private:
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    FFoo foo;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    EBar bar;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    TEnumAsByte<EBaz::Type> baz;
 
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    bool _bool;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    uint8 _uint;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    int32 _int;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    float _float;
 
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    FName name;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    FString string;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    FText text;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    FVector vector;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    FRotator rotator;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    FTransform transform;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    UObject* _object;
 
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    FMatrix matrix;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    FQuat quat;
 
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    TArray<int32> _array;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    TMap<int32, int32> map;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    TSet<int32> set;
 
#if 0
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    uint16 _uint16;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    uint32 _uint32;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    uint64 _uint64;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    int8 _int8;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    int16 _int16;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    int64 _int64;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    double _double;
 
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    FMatrix2x2 mat22;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    TStaticArray<int32, 10> staticArray;
#endif
};

f:id:PaperSloth:20180201010405p:plain

UE4 ヒットストップの実装について

※1点修正があったため追記しました。(2018/01/31 1:22)
詳しくはページ下部をご覧ください。

環境

Unreal Engine 4.17.2

Time Dilationについて

ヒットストップの実装に関してはGlobal Time Dilationの値を変更するだけで簡単に実装ができます。
Time Dilationの説明について特に知る必要がないという人は読み飛ばしてください。

ここではTime Dilationの種類等について解説します。
Time Dilationは初期値が1.0です。
デフォルトの設定では
最小値は0.0001
最大値は20.0
となっています。
1を超える値を設定した場合、例えば2.0の場合は2倍速になることを表しています。
逆に1未満の場合、例えば0.5の場合は通常の1/2の速度になることを表しています。

基本的には下図のようなCustom Time DilationとGlobal Time Dilationを使用します。
f:id:PaperSloth:20180128231743p:plain

Custom Time Dilationとは

Custom Time DilationはActorに設定されたActorごとの速度を表します。
定義は下記のActor内に記述があります。
Engine/Source/Runtime/Engine/Classes/GameFramework/Actor.h
Engine/Source/Runtime/Engine/Private/Actor.cpp

Actorの更新呼び出しの中で
下図のように使用されています。

Target->TickActor(DeltaTime * Target->CustomTimeDilation, TickType, *this);	

Global Time Dilationとは

これは名前にGlobalとあるようにゲーム中の更新に関わります。
定義箇所は下記です。
Engine/Source/Runtime/Engine/Classes/GameFramework/WorldSettings.h
Engine/Source/Runtime/Engine/Private/WorldSetting.cpp

因みにC++側で使用する際はほとんどの場合では
代わりにGetEffectiveTimeDilationを使用してください。という警告があります。

先程最小値は0.0001で最大値は20.0と書きましたが、この設定は変更することが出来ます。
f:id:PaperSloth:20180128232843p:plain

World Setteingsタブの最下部に隠れたパラメーターとして
Min Global Time Dilation, Max Global Time Dilationがあります。
BlueprintからSet Global Time Dilationを呼び出した際にはこの値を参照してClampされています。
そのため、厳密には0を指定しても0.0001が設定されるため、完全に更新が停止するというわけではありません。

ヒットストップの実装

前置きが長くなりましたが、ヒットストップの実装は至って簡単です。
今回はMacroLibraryとして作成したものを例に紹介します。
親クラスにはActorを指定しています。

実装にはたった5つのノードを呼び出すだけの非常にシンプルな実装となっています。
f:id:PaperSloth:20180128233845p:plain

図に説明があるように
Global Time Dilationにどれくらいゆっくりにしたいかの値を設定します。
0以上1未満の値でゲーム全体をゆっくりにすることが出来ます。

次にDelayで元の早さに戻るまでの時間を設定します。

呼び出し例としては下記のような感じです。
ここではわかりやすくするためにDelayに渡す値をStop Timeという名前にしています。
通常の1/10の速度に変更し、0.15秒後に元の早さに戻るように設定しています。
※0.15秒ではなく、1.5秒後になります。
詳しくは追記したページ下部の説明をご参照ください。
f:id:PaperSloth:20180128234145p:plain

実際にヒットストップを使用した感じは下記のような感じになります。
ここでは敵の撃破時に使用しています。
容量の都合上、10FPSのGifで分かりにくいですが、こんな動きになります。
f:id:PaperSloth:20180130223753g:plain

※1点誤りがあったため、追記です。
ブログ公開後に指摘をいただきましたように
Delayノードも時間の進みが遅くなります。

これは最初、気付かずに実装すると少しハマってしまうので注意が必要です。
Global Time Dilationの影響を受けるノード
・Delay
Global Time Dilationの影響を受けないノード
・Set Timer by Event


以上のように5つのノードだけで簡単にヒットストップが実装できます。
先程の例のようにMacroLibraryにしておくと便利です。
その時はActor以上を継承したものを選択しましょう。
また、FunctionLibraryでは実装できません。
理由としてはDelayなどのLatentノードの呼び出しができないからです。
ゲームのコンボや撃破時の演出など活用できる場面は幾つかあると思います。
是非試してみてください。

UE4 文字列変換について

目次

環境

Unreal Engine 4.17.2
Visual Studio Community 2015

FStringとstd::stringの変換について

プラグイン開発を行っているとネイティブのC/C++で書かれたプラグインとのやり取りが発生することがあると思います。
その時にUE4側のstring(FString)とC/C++のstring(std::string)の変換が必要になることがあります。

よくド忘れするので、簡単に個人用メモとしてまとめます。

std::string → FString

この変換にはTCHAR_TO_UTF8マクロを使います。

FString ustr = "UnrealString";
std::string cstr = TCHAR_TO_UTF8(*ustr);

FString → std::string

この変換にはc_strを呼び出します。

std::string cstr = "CppString";
FString ustr = cstr.c_str();

TCHAR_TO_UTF8の他にも幾つかマクロが存在します。
それらの定義は下記に記述があります。
Engine/Source/Runtime/Core/Public/Containers/StringConv.h

今回紹介したものがUTF8_TO_TCHARでしたが、他にも

TCHAR_TO_ANSI(str);
ANSI_TO_TCHAR(str);
TCHAR_TO_UTF8(str);

などがあります。


Blueprintに値を公開したい場合はFStringでなければなりません。
そのため、下記のようなものはエラーとなります。

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "String")
std::string FooName;

UFUNCTION(BlueprintCallable, Category = "String")
void ConvertString(const std::string str);

UFUNCTION(BlueprintCallable, Category = "String")
std::string ConvertString();

UPROPERTYもUFUNCTIONもFStringに変換しなければ使用することはできません。
ですが、std::stringが引数、戻り値として使用できないというわけではないため
Unreal C++側での呼び出しに限定される場合は問題ありません。

UE4 Editorのショートカットキーのカスタマイズについて

目次

環境

Unreal Engine 4.18.3

エディタのショートカットキー一覧

Editor Preferences - General - Keyboard Shortcuts以下に設定項目があります。
f:id:PaperSloth:20180128161608p:plain

PauseとFrameSkipにショートカットキーを割り当てておくと
デバッグ作業がしやすくなります。
f:id:PaperSloth:20180128162146p:plain

確認のたびにEjectしてからPauseだと止めたいタイミングで止めるのが難しいですからね。

他にもショートカットキーを設定可能な項目がたくさんあります。
お好みで設定してみてください。

また、既存のショートカットキーがどんなものがあるのかを確認するためにも一通り確認しておくと作業が楽になります。