PaperSloth’s diary

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

UE4 Niagaraリンク集

  • 概要

いくつかNiagaraの素晴らしい情報が増えてきたので、まとめました。
まとめただけです。
私の書いた古いNiagara記事へのアクセスが多く
それではこれから学ぶ人にとってあまりにも不便だと思ったので書きました。

  • 目次

公式ドキュメント

以前はドキュメントもなく、手探り状態でしたが
今ではドキュメントを読むだけで基本的な動きが作れます。

  • Sprite (CPU / GPU)
  • Mesh
  • Ribbon
  • Particle Light

この辺が表現できるようになっています。
ナイアガラ エディタ | Unreal Engine ドキュメント


Content Example

バージョンは最新バージョンのものを起動することを推奨します。
古いバージョンと新しいバージョンで内容が変わることが多いためです。
Niagaraのサンプルについては
・Contents/Maps/Niagara 以下にあります。

今度は実際に動いているデータが見れるので
ドキュメントより直感的だと思います。
後半は少し複雑ですが、序盤のCurl Noiseを使ったサンプルなんかは
サクッと作れる割に派手で面白いです。
f:id:PaperSloth:20190608195320p:plain

カニミソの備忘録

カニパンチさんのブログです。
crabpunch.hatenablog.com
入門から応用まで書かれていて
1つ1つの記事が初めて触る際にも、ちょうどいいボリューム感で非常に分かりやすいです。
私の過去記事の完全上位互換なので、極力こちらに誘導したいと思っていました。
ドキュメント読んでContent Example見たけどよく分からないって人でも
安心して1歩ずつ進めるのでオススメです。

Unreal Fest登壇スライド(新しいエフェクトツール、Niagaraを楽しもう! ~Niagara作例のブレイクダウン~)

池田さんの登壇されたスライドです。

www.slideshare.net

Project Data(Forums)
UNREAL FEST EAST 2018のNiagara講演で使用したプロジェクトの公開について - Unreal Engine Forums

Forums経由でProject Dataを公開していただいています。
スライド内で分かりやすく仕組みが解説されているので、
ドキュメント見ただけではイマイチピンとこなかったという人でも
なんとなく仕組みとかフローが見えてくるのではないでしょうか。
Expressionで値を入力する部分もあって、Houdiniユーザーは馴染みやすそうですね。
Blueprintとの連携も含んでおり、BPユーザーにはすごく嬉しい内容になっていると思います。

UIデザイナーのためのUE4 Niagara入門

WidgetNiagaraの連携を行った数少ない例です。
Labo AquariaさんのCGWorldへの寄稿内容です。
cgworld.jp


GitHub
GitHub - Aquariaue4/UE4Projects

GitHubに公開していただいているので、手元で動作確認をすることができます。
RenderTargetに描画してNiagaraで参照するというのは
先程の池田さんの作例とも共通する部分ですが
こちらはWidget Blueprintとの連携を行っているのが面白いところですね。
詳しくはCGWorldの記事を見ていただけると良いかと思います。

Houdiniとの連携について

まだ情報が少ないと感じる部分です。
SideFXのForumsに投稿してくれている方がいるので、そこが一番参考になるかと思います。
support.borndigital.co.jp
まずよくある誤解としてHoudini EngineとHoudini Niagaraは別のものです。

Houdini EngineはHoudiniで作成したHoudini Digital Asset(HDA)との連携を提供します。
Houdini NiagaraはHoudiniで作成したhcsv(CSV形式)として出力したデータを
UE4にImportしてNiagaraの中で使用するためのものです。

Houdiniとの連携の仕組みとしてはHoudini Niagara Data Interfaceを使用して
Houdiniで事前に計算したposition, velocity, normal, color, id...etc を
Niagaraに渡すことによってHoudini上での動作をNiagara上で再現することが可能です。


今はどうか分かりませんが
以前に検証した際はHoudini Niagaraを有効にした場合に通常のcsv Importが
Houdiniのパラメーターとして認識されてしまいData Tableが作れなかったです。
都度Pluginを有効化/無効化するのは手間ですね。


UE4.22で試したところ、csvcsvとして認識し、hcsvはhcsvとして正しく認識されるようになっていました。

色々書いたんですが、Houdiniとの連携についてはまだ手元で試せていません。

まとめ

以上で各種リンクのご紹介は終わりです。

学習フローのオススメとしては
Document -> カニミソ -> Content Example -> Fest -> CGWorld -> Houdini
この順番が良いと思います。

Documentでまずは仕組みを理解する
カニミソで動かしながら仕組みを理解する
Content Exampleで入門から応用まで触れてみる
池田さんのProjectでBlueprint連携、応用について知る
Labo AquariaさんのProjectでさらに別の応用を知る
余力があったらHoudini試してみてほしい(個人的願望)

あと余談ですがC++Niagaraを使用する場合はBuild.csのDependencyModuleNamesにNiagaraを追加しましょうね(よく忘れる)

UE4 Blueprintで2次元配列を作成する方法

環境

UE4.22.2

Blueprintでの2次元配列の作成方法

先に結論だけを書くと

  • 配列を持った構造体を用意
  • その構造体を配列で定義

上記の2ステップでできます。


コードで示すと下記になります。

USTRUCT(BlueprintType)
struct FIntArrayElement
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Game")
	TArray<int32> IntArray;
};

UCLASS()
class PROJECT_API AExampleActor : public AActor
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Game")
	TArray<FIntArrayElement> TwoDimensionIntArray;
};

f:id:PaperSloth:20190531013637p:plain



これぐらいであれば、Blueprintでも表現可能です。

下図のようにArray(配列のメンバー)をもった構造体を定義します。
構造体の作成方法はContent Browserから
Blueprints -> Structure を選択です

次の手順でおそらく警告が出ると思うので、1つ以上の要素を追加しておきます。
f:id:PaperSloth:20190531014219p:plain


次に2次元配列をもたせたいBlueprintに変数を追加します。
その際にVariable Typeを先程作成した構造体に変更し
Arrayに変更します。

すると下図のように配列の中に配列を持った2次元配列を作ることができます。
f:id:PaperSloth:20190531014328p:plain


通常のままでは構造体になっており、使用できないため
構造体の出力ピンから構造体を分割するか
Break (構造体名)で構造体を分割して使用します。
f:id:PaperSloth:20190531014803p:plain


個人的には極力多次元配列を避けて開発したいのですが
どうしても必要という方もいると思ったので書きました。

以上です。

UE4 Unreal C++でのEnumとStringの変換について

環境

UE4.20.3
Visual Studio 2017 Community

Unreal C++でのenumについてはこちら
papersloth.hatenablog.com

Enumから文字列への変換

先ずは列挙型の宣言と定義から。

UENUM(BlueprintType)
enum class EConnectionType : uint8
{
    Multicast,
    Unicast,
    NUM    UMETA(Hidden)
};

class PROJECT_API AExampleActor: public AGameModeBase
{
	GENERATED_BODY()

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Enum")
	EConnectionType ConnectionType;
}

続いてBlueprint上でのノードの変換がこちら
f:id:PaperSloth:20190514231350p:plain


Blueprintでは上図のようにEnumからStringにCastしてくれます。
しかし、C++側ではこの機能は標準で実装されていないようです。
私が知らないだけという可能性が非常に高いですが。

今回の例は結構強引な型変換を行って実装しているため
既存機能で補えたり、より良い書き方があれば教えてください。


EnumからStringへの変換についてです。
今回は説明のためにエラー処理を省略しているため
実際に使う際はエラーチェックを行うことを推奨します。

FString AExampleActor::EnumToString(const EConnectionType Type, const FString& EnumName)
{
    UEnum* const Enum = FindObject<UEnum>(ANY_PACKAGE, *EnumName);
    return Enum->GetNameStringByIndex(static_cast<int32>(Type));
}

この書き方で動作はしますがEnumNameを都度渡したり
列挙型自体を引数に渡したりと汎用性は低いです。

文字列からEnumへの変換

特に使う場面も浮かびませんが、ついでなので書いておきます。

EConnectionType AExampleActor::StringToEnum(const FString& TypeName, const FString& EnumName)
{
    UEnum* const Enum = FindObject<UEnum>(ANY_PACKAGE, *EnumName);
    int64 Value = Enum->GetValueByName(FName(*TypeName));
    return static_cast<EConnectionType>(Value);
}


上記2つの関数はUFUNCTIONマクロを付けてBlueprint上でも使用できますが
Blueprintでは
Enum -> FString は既に用意されています。
FString -> Enum は最初に書きましたが、特に使う場面が浮かびません。


以上、こういう書き方もありますよという紹介でした。

UE4 PluginのHotReloadについて

環境

UE4.22.1
Visual Studio 2017 Community

概要

通常のProject同様にEditorからCompileボタンを押してHotReload!
というわけにはいかず悩んだ人もいるかもしれないと思ったのでメモ書きを残しておきます。

PluginのHotReloadについて

まず、EditorにあるCompileボタンでHotReloadが行われるのはGame Projectのコードのみです。

Pluginは別の手順でRecompileを行う必要があります。
Window -> DeveloperTools -> Modules を選択してModules Windowを開きます。
f:id:PaperSloth:20190507224617p:plain

あとはそのWindowからHotReloadを行いたいPluginを探してRecompileボタンを押すだけです。
f:id:PaperSloth:20190507224737p:plain


Compile Complete!
f:id:PaperSloth:20190507225143p:plain

UE4 JsonFileの読み込みについて

環境

UE4.20.3
Visual Studio 2017 Community
Windows10

概要

とりあえずでこのリポジトリに突っ込んでるJsonLoad関数を文字に書き起こしただけの備忘録です。
github.com

UE4のゲーム実行時のオプションやプロパティ等を外部ファイルで編集したいとか
用途は何でもいいんですが、JsonFileを使いたい時があるのでLoaderのメモ書きを残しておきます。

JsonFileの読み込みについて

まずJsonLoaderを作成するにあたって、UE4で既存のModuleを利用するため参照の追加が必要です。
ProjectのBuild.csにJsonを追加します。

PublicDependencyModuleNames.AddRange(
    new string[]
    {
        "Core",
        "Json", // 追加
    }
);


続いて実際のLoad処理を書いていきますが、UE4側で既にJsonObject等の便利なクラスが用意されているので、そちらを使っていきます。
今回は雑把にBlueprintFunctionLibraryに書いていきます。



次に簡単なJsonを用意しました。
とりあえず一通り使うであろうbool, int, array, string, vector(float)が入っています。

// Example.json
{
    "isFullScreen": false,
    "windowWidth": 1280,
    "exampleArray": [
        {
            "exampleString": "Hello Json",
            "offset": {
                "x": 100.0,
                "y": 0.100,
                "z": 3.14
            }
        }
    ]
}


ここまでで一旦JsonObjectとjsonの作成ができました。
しかし、このままでは利用できないためJsonObjectから実際に値を取り出すコードを簡単に書いていきます。

#include "JsonFunctionLibrary.h"

// pathは (ProjectDir)/Json/Example など
bool AExampleActor::LoadJson(const FString& Path)
{
    const auto JsonObject = UPSJsonFunctionLibrary::LoadJsonObject(JsonFile);
    if (JsonObject.IsValid() == false)
    {
        return false;
    }

    MaxFps = static_cast<float>(JsonObject->GetNumberField("MaxFps"));
    IsFullScreen = JsonObject->GetBoolField("isFullScreen");
    WindowWidth = JsonObject->GetIntegerField("windowWidth");

    const auto ArrayField = JsonObject->GetArrayField("exampleArray");
    for (const auto Field : ArrayField)
    {
        const auto ObjectField = Field->AsObject();
        ExampleString = ObjectField->GetStringField("exampleString");

        auto const OffsetField = ObjectField->GetObjectField("offset");
        Offset.X = static_cast<float>(OffsetField->GetNumberField("x"));
        Offset.Y = static_cast<float>(OffsetField->GetNumberField("y"));
        Offset.Z = static_cast<float>(OffsetField->GetNumberField("z"));
    }
    return true;
}

UE4 Editorでの動画像の撮影について

環境

UE4.20.3
Windows10

概要

SNSやHP等で制作中のスクリーンショットをアップすることはよくありますね。
その中でEditor上でスクリーンショットを撮影される方も多いでしょう。
ですが、せっかくの良いゲームなのに
デバッグログが出ていたりEditorOnlyのGUIが表示されているとすごく完成度が低く見えてしまい残念に感じます。
少しでも良いゲームがもっと良く見えるようになるといいなと思います。

ゲームのスクリーンショットの撮影について

まず、UE4ではF9キーを押下することでスクリーンショットを撮影することができますね。
撮影した画像は
(ProjectDir)\Saved\ScreentShots\Windows\ScreentShot(連番).png
に保存されます。
f:id:PaperSloth:20190129200652p:plain
ここまでは特に問題ありませんね。

EditorでHidden In Gameが有効なActor/Componentを非表示にする

ViewportでGキーを押下することでGameViewの切り替えができます。
Hidden In Gameのフラグが立っているActor/Componentを非表示にできます。

先ずありがちなのが、CollisionやSpline等の実行中に表示されないComponentがスクリーンショットに写っている例です。

「新ステージを実装しました!」と下記のような画像が出てくるよりは
f:id:PaperSloth:20190129201439p:plain

下記のような画像の方がまだいいですね。
f:id:PaperSloth:20190129201601p:plain

Editor画面がまるまる写っている場合

ViewportでF11キー押下でImmersive Modeにしてからスクリーンショットを撮ることで回避できます。

これはほとんど見かけませんが、Editor画面がまるまる写っている例です。
f:id:PaperSloth:20190129201946p:plain

見たいのはあくまでもゲーム画面なので開発における技術ブログでもなければ
Editor画面は不要です。

UE4.20.3の場合はF9キー押下で普通に撮影すればこうはなりませんが
Windows標準のスクリーンショット機能で撮影をした場合などでしょうか。

Lightmap Rebuildの警告やPrintStringやAddOnScreen系のログが出ている。

Console CommandからDisableAllScreenMessagesを打ちましょう。
再度表示したい場合はEnableAllScreenMessagesです。

これが一番多くて一番ダサいですね。
f:id:PaperSloth:20190129202844p:plain

実は警告の下にうっすらと
「DisableAllScreenMessages'to suppress」と書かれています。


以上です。
せっかくのステキなアート、かっこいいゲームを作ってもこれが出てるだけでげんなりします。
ゲーム本来のキレイな絵が見れる頻度が増えることを祈ります。

 

SDL SDLの導入について

環境

Windows 10
Visual Studio 2017 Community
SDL 2.0.9

SDLとは

SDL (Simple DirectMedia Layer) は、Graphic, Sound系のAPIを提供するC言語マルチプラットフォーム対応のライブラリ。

公式サイトは下記
Simple DirectMedia Layer - Homepage

Forumを見れば分かるのだが現在も使用しているユーザーはいる。
https://discourse.libsdl.org/


SDLを使用している書籍は下記等がある。
で、意外と導入で躓いたという人もいるかもしれないと感じたのでこの記事を書くに至った。

オンラインゲームを支える技術ではSDL1.2系が使用されている。

オンラインゲームを支える技術  ??壮大なプレイ空間の舞台裏 (WEB+DB PRESS plus)

オンラインゲームを支える技術  ??壮大なプレイ空間の舞台裏 (WEB+DB PRESS plus)

ゲームプログラミングC++ではSDL2.0.3が使用されている。

ゲームプログラミングC++

ゲームプログラミングC++


SDLの導入

まずは下記よりDownloadを行う。
もしリンクが切れていたらブログトップの公式サイトのリンクからDownloadページにいってください。
Simple DirectMedia Layer - SDL version 2.0.9 (stable)

今回はDevelopment LibrariesのVC++を使用する。


1. コンソールアプリケーションを新規に作成
 適当に空のプロジェクトで良い

2. ダウンロードしたファイルを適当な場所(Solution\External\SDL とか)に解凍

3. SDLのインクルードディレクトリの指定。
 構成プロパティ/C/C++/全般/追加のインクルードディレクト
f:id:PaperSloth:20190122220010p:plain

4. 追加のライブラリディレクトリの指定。
 リンカー/全般/追加のライブラリディレクト
f:id:PaperSloth:20190122220328p:plain

5. 追加の依存ファイルの指定。
 リンカー/入力/追加の依存ファイル
  SDL.libとSDLmain.libを追加
f:id:PaperSloth:20190122220551p:plain

6. DLLをビルド時にコピー
 ビルドイベント/ビルド後のイベント/コマンドライン
  xcopy "(SDLへのパス)\*.dll" "$(OutDir)" /i /s /y を入力
f:id:PaperSloth:20190122220848p:plain

ひとまずここまでで動かすための前準備が完了。

SDLを使用する際の注意点

まず、SDLを使用する際に下記の記述をするとエラーになってしまいます。

#include "SDL.h"

int main()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    // メイン処理
    SDL_Quit();
    return 0;
}

エラーメッセージを見てみると
LNK2019 未解決の外部シンボル _SDL_main が関数 _main_getcmdline で参照されました。
と出てきます。

これはSDL_main.h内でmainでdefineが定義されているからです。

#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE)
#define main    SDL_main
#endif

また、SDL_main.h内にはメイン関数は次のように定義してくださいと書かれています。

int main(int argc, char *argv[])


そのため、SDLを使用する際には引数付きのメイン関数を定義する必要があります。

void main() // NG!
int main() // NG!
int main(int argc, char* argv[]) // OK
int main(int argc, char** argv) // OK
#include "SDL.h"

int main(int argc, char** argv)
{
    (void)argc;
    (void)argv;
    SDL_Init(SDL_INIT_EVERYTHING);
    // メイン処理
    SDL_Quit();
    return 0;
}

ひとまずWindow, Rendererを作成してみるとこんな感じになります。
f:id:PaperSloth:20190122225202p:plain

DirectXOpenGLに比べるとすごく簡単なので、C++でとりあえずゲームを作ってみようかなという人は挑戦してみてください。