Quantcast
Channel: historia Inc –株式会社ヒストリア
Viewing all 989 articles
Browse latest View live

[UE4] 「エディタの環境設定」や「プロジェクト設定」に項目を追加する

$
0
0

今回は、C++でエディタ機能を拡張して「エディタの環境設定」や「プロジェクト設定」ウィンドウ内に、独自の項目を追加する方法をご紹介します。

 

いきなりですが、ソースコードです。

 

まずは、設定項目をプロパティとして保持するクラスを用意します。

デフォルト値はコンストラクタで設定しておきましょう。

#pragma once

#include "MyEditorSetting.generated.h"

UCLASS(config=Editor, defaultconfig) // ※1
class UMyEditorSetting : public UObject
{
	GENERATED_UCLASS_BODY()

public:
	UPROPERTY(EditAnywhere, config, Category=MySetting)
	bool Check0;

	UPROPERTY(EditAnywhere, config, Category = MySetting)
	int32 Value0;
};

#include "MyProject.h"
#include "MyEditorSetting.h"

UMyEditorSetting::UMyEditorSetting(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
	, Check0(true)
	, Value0(123)
{
}

続いて、このクラスをSettingModuleに登録します。

これは、モジュールのStartupModule()とShutdownModule()をオーバーライドして行います。

#include "MyProject.h"

#include "ISettingsModule.h"
#include "MyEditorSetting.h"

#define LOCTEXT_NAMESPACE ""

class FMyProjectModule : public FDefaultGameModuleImpl
{
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
};
IMPLEMENT_PRIMARY_GAME_MODULE(FMyProjectModule, MyProjectModule, "MyProject" );

void FMyProjectModule::StartupModule()
{
	if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"))
	{
		SettingsModule->RegisterSettings(
			"Editor", // ※2
			"MySettingCategory",
			"MySetting",
			LOCTEXT("MySettingName", "MySetting"),
			LOCTEXT("MySettingDescription", "My setting discription"),
			GetMutableDefault()
			);
	}
}
void FMyProjectModule::ShutdownModule()
{
	if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"))
	{
		SettingsModule->UnregisterSettings(
			"Editor", // ※3
			"MySettingCategory",
			"MySetting"
			);
	}
}
#undef LOCTEXT_NAMESPACE

 

これで、エディタを起動して「エディタの環境設定」を開くと、↓のように項目が追加されています。

EditorSettings

 

また、この場合、設定した内容は DefaultEditor.ini に保存されます。
保存先を変えたい場合は、ソースコードの※1の箇所を編集します。
config=Editor なので、保存先が DefaultEditor.ini になっています。
config=Engine であれば、保存先は DefaultEngine.ini になります。

 

同じように「プロジェクト設定」に項目を追加したい場合は、※2,※3の箇所を、”Editor”から”Project”に変更すればOKです。

 

ここで設定した値は、下記のようにC++コード中から参照できます。

const UMyEditorSetting* MyEditorSettings = GetDefault<UMyEditorSetting>();
MyEditorSettings->Check0;
MyEditorSettings->Value0;

 

エディタ拡張やプラグイン機能のオプション化など、様々な使い道があると思います。
是非お試し下さい。


[UE4] ちょっとだけ幸せになれるブループリント

$
0
0

今回はブループリントのマイナーな(わたくし調べ)ちょっとうれしい機能をいくつかご紹介しようと思います。

 

クリックのみで変数の型変更!

ブループリントの各変数左横にある変数のアイコンを左クリックすると型の変更、

右クリックをすると配列か単体かの変更ができます。

variconclick variconleftclick variconrightclick

 

 

死んだ変数を再利用!「Create Variable」

下のような何らかの関数「FunctionA」のうち一部をコピーして別の関数「FunctionB」にペーストすると

functiona

functionbpaste

変数が灰色になり、そのままノードを組んでも

コンパイル時に「The property associated with Function A Local Var could not be found」と変数が見つからない旨のエラー出てしまい使えません。

 

ここで変数を左クリックで選択した状態にし、

ノード上で右クリックをすると以下のように「Create variable ‘変数名’」「Create local variable ‘変数名’」が現れるのでクリックします。

selectnodeandcreatevariable    createdvariabe

するとこのように変数名が維持されたまま新規の変数が自動的に作られます!

関数をまたげるだけでなく、ブループリント間も同様の操作でまたげるので

一部関数をBlueprintFunctionLibraryに纏める必要が出てきた際などに使えそうです。

 

 

Compact Node Titleでコンパクトに!

ブループリントで加算代入演算子+=のような計算をしようとすると以下のような感じになると思います。

plusequal

コードで同じ計算をするのに比べて、なんとなく冗長な感じがします。

もう少しコンパクトにしたいです。

そこで新規BlueprintFunctionLibraryを用意し、「Add」という名前で関数を作ります。(※ArrayのAddと名前が被るので実用の際はもう少し抽象度の低い名前にすることをお勧めします)

InputにInt型の変数を2つ指定し、片方の「Pass-by-Referrence」にチェックを入れます。

「Pass-by-Referrence」が表示されていない場合は、変数名左の右向きの三角▷をクリックしてください。

addnodeinput

ノードは以下のように組みます。

addnodenoding

入ってきた「Value」にAddValueを足すという処理です。

そしてこれが一番重要です。

関数のDetailsのGraph内にある「Compact Node Title」に「+=」といれます。

するとノードを「+=」などで検索した際に作成した「Add」が候補に現れます。

searchplusequal

これを使って「Num += 10」を書くととてもコンパクトになります!

plusequalfinal これだけ!

こんな感じでCompact Node Titleは、

C++の演算子のオーバーロードのような感じの使い方に向いていると思います。

頻繁に使うユーティリティなどもコンパクトにしてしまうのがいいかもしれません。

 

 

関数のInput/Outputピンを楽に増やす!

とある構造体「Structure」の一部のメンバ変数のみゲットしたい場合があるとします。

structgetterfirst

structgetternew

関数のOutputの欄にあるNewをクリックして変数名を指定し、型を合わせて一つ一つOutputのPinを作っていくのもいいですが、

以下のようにPinからドラッグでReturnノード上にもっていくと「Add Pin to Node」というのが出てきます。

structgetteraddpin

Returnノード上でドラッグ&ドロップをするとなんと

autoaddpin

自動で変数名と型を引き継いでOutput Pinを作ってくれます。

これを利用してほぼマウス操作のみの4操作だけで下のようなGetterが作れてしまいます。

structgetterfinal

 

同様にInput Nodeにドラッグ&ドロップをすることでInput Pinが作れてしまいます。

structsetter

structsetterfinal

とっても簡単ですね。

 

 

以上、ちょっとだけ幸せになれるブループリントでした。

[UE4] レベルストリーミングについて

$
0
0

今回はレベルの読み込み回りについてのお話をしたいと思います。
話を進める上で、少し内容が混乱してしまうため、便宜的に単語を定義付けたいと思います。

レベル UE4で拡張子がumapになっているアセットのこと
マップ パーシスタントレベルと複数のサブレベルで構成されるレベルのこと

UE4にはレベルを複数に分ける機能があります。
もちろんレベルを分けずに、親レベルであるパーシスタントレベルに全てのアクターを配置することも可能ですが、レベル分けを活用することで、よりゲームを作りやすくすることが可能です。

 

レベルを分ける

レベルを分ける事によるメリットは様々ですが、敢えて挙げるとすれば以下のような内容ではないでしょうか。

  • マップを切り替える事なく、レベルの状況を切り替える事が出来る
    (例:アクションゲームを作る際、ステージごとにレベルを分けておくと、ステージクリアした時に次のステージにすぐ切り替えられる)
  • 作業者単位でレベルを分けることで、同時に一つのマップを編集できる
    (例:RPGなどで背景用のレベルとギミック用のレベルをわけておくと、背景担当とギミック担当で同時に作業をすすめる事ができる)
  • 一時的に配置したいアクターなど、用途によって分けることで管理が楽
    (例:デバッグ用レベルを作ることで、リリース時にそのレベルだけを破棄すれば楽に完成版からデバッグ機能を無くす事ができる)

さて、実際にレベル分けを行った場合、次に必要になってくるのはレベルの読み込みタイミングの管理です。
そこでレベルの追加方法を確認しながら解説していきたいと思います。

まず、レベルウィンドウのレベルメニューから「新規作成」を選択肢し、新しいレベルを追加します。
1

この時追加した新規レベルは、そのまま実行しても読み込まれません。
これはレベルのデフォルトのストリーミング方法がブループリント制御になっているからです。
2

デフォルトのストリーミング方法

ブループリント ブループリントによって制御します
常にロード済み パーシスタンスレベルを読み込んだ際、自動的に一緒に読み込まれます
読み込み方法は同期読み込みで、このレベルの読み込み及び表示が完了するまで、次のサブレベルの読み込みは発生しません

 

レベルを読み込むタイミングを決める

今回はブループリントによる制御で話を進めます。では、ブループリント制御にしたい場合はどんな時でしょうか。

  1. マップ遷移直後に該当レベルを非同期で読み込みたい場合
    すぐに必要のないレベルなどは非同期読み込みにすることで、マップ遷移時のロード時間を早める事が期待できます。
  2. 任意のタイミングでレベルを読み込みたい場合
    マップ遷移後すぐには必要ありませんが、ある特定のタイミングでレベルが必要になった時に読み込みたい場合です。

レベルの使用意図に合わせてこれらを使い分けます。
ちなみに1のパーシスタントレベルが読み込まれた際に自動で非同期読み込みを行いたい場合は、レベル詳細から設定できます。

変更したいレベルを選択し、レベルの詳細アイコンを押すと、そのレベルの詳細ウィンドウが開きます。
3

Initially Loaded チェックマークを入れると自動で非同期読み込みを行います
Initially Visible チェックマークを入れると読み込み後に表示まで一緒に行います

今回は任意のタイミングでのレベルの管理を行いたいので、設定はそのままにしておきます。

 

任意のタイミングでレベルを読み込む

さて、では任意のタイミングでレベルを読み込む手段ですが、これはUE4だと2つ用意されています。

  1. Level Streaming Volumeを使用する
    ボリューム内にプレイヤーが侵入した場合に、指定されたレベルを指定した方法で読み込みます
    ボリューム外に出た場合はアンロードされます
  2. ブループリント内でLoad Stream Levelノードを使用する
    レベルブループリントなどで任意のタイミングに、引数のレベルを設定した方法で読み込みます
    ちなみにアンロードしたい場合はUn Load Stream Levelノードを使用します

まず1のLevel Streaming Volumeを使用する場合です。
このボリュームは少々特殊で、パーシスタントレベルに置くことでしか効果を発揮しません。
レベルの読み込みを管理するボリュームなので、必ず読み込まれるパーシスタントレベルに置くのは当然ですし、そもそも設定しようとすると警告が出ます。
4

次に各サブレベルのレベル詳細で、対象となる配置したLevel Streaming Volumeを選択して紐付けます。
5

これでボリューム内にプレイヤーが侵入した際に、紐付けたレベルが読み込まれるようになります。
読み込み方法についてはボリューム側で設定できます。
6
Streaming Usage

SVB Loading 非同期読み込みのみ
SVB Loading and Visibility 非同期読み込み後レベル表示(デフォルト設定)
SVB Visibility Blocking on Load 同期読み込み後、表示完了まで待つ
SVB Blocking on Load 同期読み込みのみ行う
SVB Loading Not Visible 非同期読み込み後に非表示状態を保つ。Load Stream LevelやShould Be Visbleでも表示状態にならないので注意

次に2のブループリント内でLoad Stream Levelノードを使用する場合です。
この関数は処理待ちが発生するLatentノードなので、関数では使えません。使用する場合はイベント内やマクロで使用しましょう。

7

Level Name レベル名
Make Visible After Load 読み込み後に表示を行うかどうか
Should Block on Load 同期読み込みを行うかどうか

 

レベルの表示タイミングを制御する

さて、これでレベルの読み込み関連は一通り紹介しましたが、もう少し踏み込んでみましょう。
それはレベルの表示タイミングです。
レベルには、ロード済の状態でも表示状態と非表示状態の2種類の状態が存在します。
普段エディタで作業している時に、レベル単位で表示非表示を切り替える場合もあるかと思いますが、それと同じようにゲーム中にレベル単位で表示の切り替えが可能です。

ちなみにレベルウィンドウの各レベルの左横にある目マークのアイコンでどちらの状態か確認することができます。
8

ではレベルをロードするタイミングと表示するタイミングで分ける必要があるでしょうか?
メリットはあります。例えばメモリには余裕があるけど描画速度がキツイ…といった場合に有効です。
具体的にはある程度広いマップを使ったゲームなどが該当すると思います。
そこで背景レベルなどをいくつかに分割し、表示が必要でない箇所は非表示状態にしておけば、必要な時に素早く表示状態にできるというわけです。
似たような機能としてUE4にはWorldCompositionというオープンワールド用の機能が存在しますが、それを使わない場合はこういったテクニックを使うという選択肢も視野に入れてみてはどうでしょう。

話を戻しましょう。実際の実装方法としましては、二通り存在します

  1. Load Stream Levelノードを使用する
    引数のMakeVisibleAfterLoadをTrueにしておけば、レベルが読み込まれている状態に再度呼び出すと表示処理のみが実行されます。
    ただしこの方法だと非表示への切り替えできません。
  2. Get Streaming Levelを使用して直接Should be Visibleを設定する
    Trueにすることで表示状態にでき、Falseにすることで非表示状態にもできます。
    直接LevelStreamingのメソッドを触るのでちょっとプログラマ的には気持ちが悪いかもです。
    9

さて、このように表示タイミングを分けた場合、どうしても表示完了のタイミングを知りたいという状況があるかと思います。なぜならUE4のレベルの表示は一瞬で切り替わるものではなく、次第に表示されるような仕様になっているからです。つまり表示完了待ちというタイミング発生するわけです。
そこで指定レベルの表示が完了したかを調べる方法があります。

Get Streaming LevelからIs Level Visibleで判定を取る事が可能です。
10

これを実際に使える形としてマクロ化したものがこちらになります。
11

そして実際のマクロの使用例がこちらになります。引数を配列にすることで複数のレベルに対して同時に判定を行っていますが、その必要が無い場合はもっと中身は簡潔なもになるかと思います。
12

また、コンソールコマンドの「stat LEVELS」でもレベルの読み込み状況がリアルタイムに確認できるため、デバッグ時はこちらを積極的に活用していきましょう

このようにレベルの読み込みや表示タイミングを状況に合わせて自在に操れるようになれば、レベル管理も様々な状況で対応できるのではないでしょうか

 

おまけ

Level Streaming Volumeですが、ボリュームの設定方法としては他と違って少し特殊です。
レベル詳細の方で各ボリュームと紐付けるのはワークフロー的にちょっと…と思う方もいるかもしれません。
そんな時はボリュームクラスを基底クラスにブループリントを作成できるようにエンジン側を弄ることで、解消できるかと思います。

変数で対象のレベル名を指定できるようにします。
1314

ブループリントでボリューム内に入った時に対象レベルを読み込み(或いは表示)、出た時に破棄(或いは非表示)といった処理にすれば、他のボリューム配置と同様のワークフローで完結します。

15

[UE4] 任意の形状のボリュームを作る

$
0
0

今回は、任意の形状のボリュームやコリジョンなどを作成する方法を紹介したいと思います。

ゲームを作っていく上で、ダメージ床や特定の場所によるカメラの切り替えなど、侵入判定によって様々な挙動を変えたいときがあります。
そういった場合に役に立つのがトリガーボックスですが、それだとボックス型の判定しか取ることができません。ですが、トリガーボリュームを使う事で、ボックス型以外の形状で判定を取る事ができます。

UE4にはBSPブラシを自力で作成する機能があるので、今回はこれを使用します。

まずジオメトリの編集モードに切り替え、ペンを選択します。
1

次にビューモードをパースペクティブビューからトップビューに切り替えます
2

この際、自動でワイヤーフレームに切り替わるので、作業しやすいようにライティングなどに描画を切り替えます。
3

これでBSPブラシの作成が可能になります。
この状態で、任意の場所にスペースキーを押す事で、頂点が生成されます。
もし間違えた場合はバックスペースキーで頂点を取り消す事も可能です。
4

最後にエンターキーを押すことでBSPブラシが完成します。
5

次に作成したBSPブラシのアクターを選択した状態で、アクター詳細からConvertActorを選択します。
今回はトリガーボリュームに変換しますが、用途によって侵入不可用のブロッキングボリュームなど様々なボリュームに変換可能です。
7

※BSPブラシをConvertActorで変換した際、バグなのか変換前のBSPブラシがそのまま残ってしまいます。ですが、別のBPSブラシを作成したタイミングで、残っていた変換前のBSPブラシは削除されます。

これでBSPブラシによる任意形状のボリュームの完成ですが、これだけだと高さが合っていないと思うので、最後にZ軸をスケーリングなり移動させるなりして微調整しましょう。
ちなみに通常のBSPブラシ同様、後から各頂点の座標を編集する事も可能です。
8

後はレベルブループリントなどでボリュームに侵入した場合や出た場合の処理を書けば完成です。
※ボリュームもブループリント化できればもっと色々と用途を増やすことができるんですけどね…
9
10

[UE4] スプライン移動するキャラクターを作る

$
0
0

以前、スプラインの移動処理をコンポーネント化する方法をご紹介しましたが、今回はそのスプライン移動の機能を更に充実化させ、キャラクターを移動させる方法の一つをご紹介したいと思います。

 

ちなみに実装後の動画がこちらになります。

 

さて、前回までの機能は、移動処理にSetActorLocationAndRotationを使用していたため、キャラクターに使うには色々と問題がありました。例えば、スプラインを地面に添って設置しなければキャラクターが地面に浮いてしまったり、埋もれたりしてしまうからです。接地処理に関しては、キャラクターの足元からレイを飛ばして地面の座標を取得する方法などが考えられますが、毎フレームやるには処理が重いためあまり良い方法でありません。
そこでSetActorLocationAndRotationを使わず、移動処理のみをカスタマイズした新しいスプライン移動用のコンポーネントを作成したいと思います。

まずは準備として以前作成したコンポーネントに若干修正を加えます。
以前はTick内でForceMove関数を使用して移動させていましたが、強制移動とは別に通常移動用の処理を用意して、こちらを使うことにします。
そこで、新しく用意する通常移動処理の関数名をMovingProcessとします。

Functions

関数名 Description
MovingProcess 現在の移動量から通常の移動

MovingProcess関数

関数の中身は以前のForceMove関数と同じ処理を書きます。ただし、前回の移動関数には戻り値がありませんでしたが、今回はResultというBool型の戻り値を関数に追加します。これはこの後作る派生クラスで、移動関数をオーバーライド出来るようにするためです。

1

 

通常移動処理用の関数を用意したら、Tick内はこちらを使用するように差し替えます。

Event Tick

2

 

次に、スプラインを設定する関数であるSetSpline関数に機能を追加します。

SetSpline関数

引数に移動速度と、開始時にスプラインの始端へ強制移動するかのフラグを追加します。強制移動を行う際は、もちろんForceMove関数の方を使用します。

3

 

では早速新しくキャラクター用のスプライン移動コンポーネントを作成します。
まず、既存のスプライン移動コンポーネントを基底にした新しいコンポーネントを作成します。名前はとりあえずSplineCharacterMoveComponentとします。

4

次に基底クラス内の関数、MovingProcess関数をオーバーライドして関数を書き換えます。
この時、基底クラス側の関数に引数がないとオーバーライドした際に自動でイベント扱いとなるので注意して下さい。

5

6

使用したのはPawnのAddMovementInputです。Pawnの関数なので、オーナーをPawn型にキャストしています。
コンポーネントはどのブループリントクラスでも使用できるため、オーナーが必ずコンポーネント作成者の意図した型にならない事は注意して下さい。

これでキャラクター用の移動用スプラインコンポーネントは完成しました。
あとは実際にスプラインアクターをレベルに配置し、それをコンポーネントを追加したキャラクターが参照することで、スプラインに沿って移動できるようになります。

7

 

今までは移動処理の中身でスプラインの座標を直接取得していましたが、今回はスプラインの向き情報を利用してAddMovementInputでキャラクターを動かしています。ですので、移動速度に実際のキャラクターの移動速度を渡しておかないと、スプラインと実際の移動座標がずれてしまうのにご注意下さい。
また、開始時に強制移動を行っている理由も同じです。開始位置がスプラインの始端になっていないと、スプライン通りに移動する事ができないためです。通常移動と強制移動で処理を分けたのはこのためでした。

 

このようにやや癖はありますが、スプラインの向きのみを参照してキャラクターを動かしているので、凹凸の地面でも気にせずスプラインを引くことができます。わざわざ凹凸に合わせてスプラインを配置しなくても、キャラクターは勝手に凹凸に合わせて走ってくれるでしょう。
また、移動の処理自体はキャラクターのCharacterMovementの機能を使って動いているため、例えばOrientRotationtoMovementにチェックマークを入れれば、キャラクターは移動方向に合わせてそちらを向く事が可能です。

8

このように利点は大きいですが、やはりスプラインの座標を参照しているわけではないので、どうしても厳密にスプラインをなぞる事は難しいです。ですので、より正確にスプライン移動をしたい場合は、MovingProcessを自由にカスタマイズしてより正確なものを目指しましょう。

[UE4] Unityビルドシステム

$
0
0

今回は、UE4のC++ビルドシステムのオプションの1つである、Unityビルドシステムについてご紹介します。
某ゲームエンジンとは全くの無関係です。あくまでUE4のお話です。

また、C++についての知識を前提とした、プログラマ向けの内容になりますので、ご了承下さい。

 

今回の説明には、公式サンプルの1つであるShooterGameプロジェクトを使用します。
UE4公開初期からある、C++コードを使用したプロジェクトです。

 

まずは、さくっとこのプロジェクトをビルドしてみて下さい。
構成はデフォルトのまま、「Development Editor」でOKです。

ココで、ビルドログを確認します。

-------------------------------------------------------------------------------
Initializing...
--------------------Project: Default-------------------------------------------
PCH.ShooterGame.h.cpp (0:23.28 at +0:00)
Module.ShooterGame.cpp (0:15.18 at +0:23)
ShooterGame.generated.cpp (0:02.46 at +0:38)
ShooterGame.rc (0:00.09 at +0:40)
ModuleVersionResource.rc.inl (0:00.07 at +0:41)
UE4Editor-ShooterGame.dll (0:00.95 at +0:41)

こんな感じでビルドログが流れて、ShooterGameモジュールがビルドされているのが分かるかと思います。

 

ココで、1つ疑問が出てきます。
上記のログは、各C++ソースコードのコンパイルから、dllの生成までのログです。
しかし、ShooterGameプロジェクトに含まれている、多数のソースコードをコンパイルしている形跡がありません。

 

実は、ログのなかにある「Module.ShooterGame.cpp」に、このモジュール内の全てのcppファイルが含まれているのです。

 

どういうことなのか、確認してみます。下記のフォルダを覗いてみて下さい。

ShooterGame/Intermediate/Build/Win64/UE4Editor/Development/ShooterGame

unity_intermediate

ココは、ビルドのための中間ファイルが保存されるフォルダです。リンク前のobjファイルもココに配置されています。

先ほどのビルドログに出ていた「Module.ShooterGame.cpp」も見つかりました。
早速、中身を見てみます。

// This file is automatically generated at compile-time to include some subset of the user-created cpp files.
#include "中略\ShooterGame\Source\ShooterGame\Public\ShooterGame.h"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterEngine.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterGameDelegates.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterGameInstance.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterGameModule.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterGameUserSettings.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterGameViewportClient.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterTeamStart.cpp"
//以下略...

ハイ、なかなかに恐ろしいですね。コレがUnityビルドシステムです。

リンク時間の短縮などの目的で、モジュール内のソースコードを全てincludeして、まとめてコンパイルしているそうです。

 

1つのモジュール内のソースコードが多い場合には、いくつかに分割されるようです。
UE4本体のソースコードをビルドした事があれば、ビルドログから下記のようなファイル名を見たことがあるかと思います。

Module.Core.1_of_7.cpp
Module.Core.2_of_7.cpp

 

UE4のC++ビルドでは、デフォルトでUnityビルドが有効になっています。
そのため稀に事故が起きてしまう場合もあります。

  • 必要なincludeを記述していないのに、コンパイルが通ってしまう
  • 無名ネームスペース内で定義した変数名や関数名が衝突する
  • 特定のコード内でしか使用しないつもりのマクロが、他のコード中でも反映されてしまう

といった場合には、ココを疑ってみても良いかもしれません。

 

Unityビルドは、必要であれば無効化することも出来ます。

その場合には、モジュールの .Build.cs に以下のように記述します。

BuildConfiguration.bUseUnityBuild = false;

この状態でビルドし、ビルドログや先ほどの中間ファイルの保存先を見てみると、各cppファイルが個別にコンパイルされていることが分かると思います。

 

下記のように書けば、DebugGame構成でのみUnityビルドを無効化する、といったことも出来ます。

if(Target.Configuration == UnrealTargetConfiguration.DebugGame)
{
BuildConfiguration.bUseUnityBuild = false;
}

 

Unityビルドが有効な場合、リンク時間が短縮される代わりに、少しの編集でもコンパイル時間が長くかかってしまうことになります。
状況に応じて使い分けると、少し快適に開発が出来るようになるかもしれません。

 

[UE4] C++プロジェクトをWindowsからiOSのパッケージ作成を行う。

$
0
0

今回は、C++プロジェクトをWindows上からMacを使用してRemoteBuildを行い、iOSのパッケージを作成する方法をご紹介します!

 

C++プロジェクトは基本的にWindowsだけではiOSのパッケージを作成することはできません。なのでMacを使用してパッケージを作成することになりますが、MacではまだUE4は安定して動作しないこともありWindowsで開発を行うことが多いかと思います。

そうした場合に、開発中にiOS端末でチェックをしたいとなった場合に毎回Macにプロジェクトをコピーしてきてパッケージ作成を行うのはとてもめんどくさいです。Windowsからパッケージングできたほうが断然ラクになるのは間違いないですよね。

そこで活躍するのがUE4の標準機能にあるRemoteBuild機能です。RemoteBuildを行えば、WindowsからでもMacを使用してiOSのパッケージを作成することが出来ます!

 

※注意!

C++プロジェクトのiOSビルドを行いたい場合は、ビルド済みエンジンではなくGitHubからDLしてきたエンジンを使わなくてはいけません。ビルド済みエンジンでは必要なファイルが存在していませんし、そもそもiOSパッケージ作成を行えません。

 

では早速、設定をしていきましょう

 

1.MACの下準備

①MACへのリモートログインを許可します。

システム環境設定→共有を開き、リモートログインのチェックボックス項目にチェックを入れます。

スクリーンショット 2016-03-08 12.22.33

②キーチェーンアクセスのシステム項目に証明書をインポートします。

1).cerもしくは.p12ファイルをダブルクリックし、キーチェーン項目をシステムに変更。追加をクリックします。

Blog_RemoteBuild_2

2)システムキーチェーンに証明書が追加されていることを確認します。

Blog_RemoteBuild_3

 

 

2.Windowの下準備

DeltaCopyをインストールします。

1)DeltaCopyDLリンクから、DonwloadLinksのWithInstallerからインストーラーをダウンロードしてください。

Blog_RemoteBuild_4

2)ダウンロードファイルを解凍後、インストーラーを起動し手順に沿ってインストールしてください。

 

3.RemoteBuildの設定

準備が完了したのでRemoteBuildの設定をしていきたいと思います。

 

①ProjectSettings→iOSを開き、iOSページのBuildカテゴリにあるRemoteBuildOptionsを設定していきます。

Blog_RemoteBuild_6

Remote Sever Name 接続するMacのPC名またはIPアドレスを入力します。例)GRAPE.local,192.168.1.1
Delta Copy Install Path 先程インストールしたDeltaCopyのパスを入力します。
Rsync User Name 接続するMacのログインしているアカウント名を入力します。
Found Existing SSH permissions file Generate SSH Key で作成されたSSH Keyのパスが入ります。入力できる項目ではないのでスルーで大丈夫です。
Override existing SSH permiissions file 既に作成されているSSH Keyファイルを選択することが出来ます。基本的には、入力する必要はないです。ほかのSSH Keyを使う場合は、Engine/Build/SSHKeysフォルダにSSH Keyファイルをコピーし、この項目でコピーしたファイルを選択します。ここを使用した場合は「Generate SSH Key」を行う必要はありませんが、パッケージング中に「Rsync User Name」で設定したアカウントにログインするためのパスワードの入力を求められるので入力します。

 

②SSH Keyを作成します。(※Override existing SSH permiissions fileにSSH Keyファイルを選択している場合は必要ありません。)

1)Generate SSH Keyボタンをクリックします。

2)初回はy/nの選択肢が出てくるのでyを入力します。

3)パスワードを求められるので「Rsync User Name」で設定したアカウントにログインするためのパスワードを入力します。

4)パスフレーズの設定を行います。入力しなくても先に進む項目です。設定する場合は入力してEnter、設定しない場合は入力しないでEnterを押します。

 再度入力を求められるので先程と同じ操作を行います。

5)最後に3)と同じようにパスワードの入力を求められるので入力します。

これで無事SSH Keyが作成されました。「Remote Build Options」の「Found Existing SSH permissions file」に作成されたSSH Keyのパスが入っていれば完了です。

Blog_RemoteBuild_7

 

4.iOSのパッケージを作成する。

①iOSのパッケージングを行うための設定をします。設定については省略しますが、UE4の公式ドキュメントに詳しく書かれているので参考にしてください。

iOS クイックスタート

設定し終わったらあとはパッケージングするだけです。

無事にipaファイルが作成されていれば完了です!

[UE4] 実機のプロファイリング!(iOS編)

$
0
0

今回は実機を使用してのプロファイルのiOS編です。Androidはこちら

 

はじめにエンジンやXcodeのバージョンによって手順など変わることがあるので今回確認した環境を書いときます。

MacBook Pro (OSX  Yosemite    Version 10.10.5 )

Xcode Version 7.2.1

UnrealEngine Version 4.10.4

またドキュメントのiOSクイックスタートを参考に実機での動作確認できる状態にしてください。

 

 

・Xcodeで起動する

今回プロファイルで使用するのは[Instruments]というXcodeでの開発では同じみの標準で備わっているツールを使用します。

なのでプロジェクトXcodeから起動する必要があります。ない場合は[~~.uproject]を右クリックし[サービス]を選択[Generate Xcode Project]で生成し、そのままエディタを起動させます。

 

・Launchし実機にアプリをインストールさせる。

実機でのデバックをしたときと同様にアプリをインストールさせます。

インストールし、実機での動作を確認できたらエディタを閉じXcodeに戻ります。

 

・Xcodeで実機を起動させる

あとはこれを実機用のスキームに。。。変更して。。。終わっ

スクリーンショット 2016-03-16 13.09.34

たと思ったのですがどうやらバージョンが変わったことで今はなくなったようです。現状あるスキームの設定を変えてもいいですが今回は実機用にスキームを追加しました。

 

・スキームの追加

新しく追加する場合は[New Sheme…]を選択しターゲットをプロジェクト名だけのものを選択し、スキーム名を[TestProject_iOS]としました。

スクリーンショット 2016-03-16 13.09.46

 

キャプチャ

追加するとスキーム選択時の一覧に表示されます。

 

・ビルド設定を切り替える

[TestProject_iOS]を選択した状態で今度は[Edit Sheme…]を選択します。

スクリーンショット 2016-03-16 13.10.56

↑の画像のような画面が出たらそれぞれ[Development]を指定し[Close]を押します。

 

 

後は[Instruments]を起動させればプロファイルすることができます

 


[UE4] 「エディタの環境設定」や「プロジェクト設定」に項目を追加する

$
0
0

今回は、C++でエディタ機能を拡張して「エディタの環境設定」や「プロジェクト設定」ウィンドウ内に、独自の項目を追加する方法をご紹介します。

 

いきなりですが、ソースコードです。

 

まずは、設定項目をプロパティとして保持するクラスを用意します。

デフォルト値はコンストラクタで設定しておきましょう。

#pragma once

#include "MyEditorSetting.generated.h"

UCLASS(config=Editor, defaultconfig) // ※1
class UMyEditorSetting : public UObject
{
	GENERATED_UCLASS_BODY()

public:
	UPROPERTY(EditAnywhere, config, Category=MySetting)
	bool Check0;

	UPROPERTY(EditAnywhere, config, Category = MySetting)
	int32 Value0;
};

#include "MyProject.h"
#include "MyEditorSetting.h"

UMyEditorSetting::UMyEditorSetting(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
	, Check0(true)
	, Value0(123)
{
}

続いて、このクラスをSettingModuleに登録します。

これは、モジュールのStartupModule()とShutdownModule()をオーバーライドして行います。

#include "MyProject.h"

#include "ISettingsModule.h"
#include "MyEditorSetting.h"

#define LOCTEXT_NAMESPACE ""

class FMyProjectModule : public FDefaultGameModuleImpl
{
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
};
IMPLEMENT_PRIMARY_GAME_MODULE(FMyProjectModule, MyProjectModule, "MyProject" );

void FMyProjectModule::StartupModule()
{
	if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"))
	{
		SettingsModule->RegisterSettings(
			"Editor", // ※2
			"MySettingCategory",
			"MySetting",
			LOCTEXT("MySettingName", "MySetting"),
			LOCTEXT("MySettingDescription", "My setting discription"),
			GetMutableDefault()
			);
	}
}
void FMyProjectModule::ShutdownModule()
{
	if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings"))
	{
		SettingsModule->UnregisterSettings(
			"Editor", // ※3
			"MySettingCategory",
			"MySetting"
			);
	}
}
#undef LOCTEXT_NAMESPACE

 

これで、エディタを起動して「エディタの環境設定」を開くと、↓のように項目が追加されています。

EditorSettings

 

また、この場合、設定した内容は DefaultEditor.ini に保存されます。
保存先を変えたい場合は、ソースコードの※1の箇所を編集します。
config=Editor なので、保存先が DefaultEditor.ini になっています。
config=Engine であれば、保存先は DefaultEngine.ini になります。

 

同じように「プロジェクト設定」に項目を追加したい場合は、※2,※3の箇所を、”Editor”から”Project”に変更すればOKです。

 

ここで設定した値は、下記のようにC++コード中から参照できます。

const UMyEditorSetting* MyEditorSettings = GetDefault<UMyEditorSetting>();
MyEditorSettings->Check0;
MyEditorSettings->Value0;

 

エディタ拡張やプラグイン機能のオプション化など、様々な使い道があると思います。
是非お試し下さい。

[UE4] ちょっとだけ幸せになれるブループリント

$
0
0

今回はブループリントのマイナーな(わたくし調べ)ちょっとうれしい機能をいくつかご紹介しようと思います。

 

クリックのみで変数の型変更!

ブループリントの各変数左横にある変数のアイコンを左クリックすると型の変更、

右クリックをすると配列か単体かの変更ができます。

variconclick variconleftclick variconrightclick

 

 

死んだ変数を再利用!「Create Variable」

下のような何らかの関数「FunctionA」のうち一部をコピーして別の関数「FunctionB」にペーストすると

functiona

functionbpaste

変数が灰色になり、そのままノードを組んでも

コンパイル時に「The property associated with Function A Local Var could not be found」と変数が見つからない旨のエラー出てしまい使えません。

 

ここで変数を左クリックで選択した状態にし、

ノード上で右クリックをすると以下のように「Create variable ‘変数名’」「Create local variable ‘変数名’」が現れるのでクリックします。

selectnodeandcreatevariable    createdvariabe

するとこのように変数名が維持されたまま新規の変数が自動的に作られます!

関数をまたげるだけでなく、ブループリント間も同様の操作でまたげるので

一部関数をBlueprintFunctionLibraryに纏める必要が出てきた際などに使えそうです。

 

 

Compact Node Titleでコンパクトに!

ブループリントで加算代入演算子+=のような計算をしようとすると以下のような感じになると思います。

plusequal

コードで同じ計算をするのに比べて、なんとなく冗長な感じがします。

もう少しコンパクトにしたいです。

そこで新規BlueprintFunctionLibraryを用意し、「Add」という名前で関数を作ります。(※ArrayのAddと名前が被るので実用の際はもう少し抽象度の低い名前にすることをお勧めします)

InputにInt型の変数を2つ指定し、片方の「Pass-by-Referrence」にチェックを入れます。

「Pass-by-Referrence」が表示されていない場合は、変数名左の右向きの三角▷をクリックしてください。

addnodeinput

ノードは以下のように組みます。

addnodenoding

入ってきた「Value」にAddValueを足すという処理です。

そしてこれが一番重要です。

関数のDetailsのGraph内にある「Compact Node Title」に「+=」といれます。

するとノードを「+=」などで検索した際に作成した「Add」が候補に現れます。

searchplusequal

これを使って「Num += 10」を書くととてもコンパクトになります!

plusequalfinal これだけ!

こんな感じでCompact Node Titleは、

C++の演算子のオーバーロードのような感じの使い方に向いていると思います。

頻繁に使うユーティリティなどもコンパクトにしてしまうのがいいかもしれません。

 

 

関数のInput/Outputピンを楽に増やす!

とある構造体「Structure」の一部のメンバ変数のみゲットしたい場合があるとします。

structgetterfirst

structgetternew

関数のOutputの欄にあるNewをクリックして変数名を指定し、型を合わせて一つ一つOutputのPinを作っていくのもいいですが、

以下のようにPinからドラッグでReturnノード上にもっていくと「Add Pin to Node」というのが出てきます。

structgetteraddpin

Returnノード上でドラッグ&ドロップをするとなんと

autoaddpin

自動で変数名と型を引き継いでOutput Pinを作ってくれます。

これを利用してほぼマウス操作のみの4操作だけで下のようなGetterが作れてしまいます。

structgetterfinal

 

同様にInput Nodeにドラッグ&ドロップをすることでInput Pinが作れてしまいます。

structsetter

structsetterfinal

とっても簡単ですね。

 

 

以上、ちょっとだけ幸せになれるブループリントでした。

[UE4] レベルストリーミングについて

$
0
0

今回はレベルの読み込み回りについてのお話をしたいと思います。
話を進める上で、少し内容が混乱してしまうため、便宜的に単語を定義付けたいと思います。

レベル UE4で拡張子がumapになっているアセットのこと
マップ パーシスタントレベルと複数のサブレベルで構成されるレベルのこと

UE4にはレベルを複数に分ける機能があります。
もちろんレベルを分けずに、親レベルであるパーシスタントレベルに全てのアクターを配置することも可能ですが、レベル分けを活用することで、よりゲームを作りやすくすることが可能です。

 

レベルを分ける

レベルを分ける事によるメリットは様々ですが、敢えて挙げるとすれば以下のような内容ではないでしょうか。

  • マップを切り替える事なく、レベルの状況を切り替える事が出来る
    (例:アクションゲームを作る際、ステージごとにレベルを分けておくと、ステージクリアした時に次のステージにすぐ切り替えられる)
  • 作業者単位でレベルを分けることで、同時に一つのマップを編集できる
    (例:RPGなどで背景用のレベルとギミック用のレベルをわけておくと、背景担当とギミック担当で同時に作業をすすめる事ができる)
  • 一時的に配置したいアクターなど、用途によって分けることで管理が楽
    (例:デバッグ用レベルを作ることで、リリース時にそのレベルだけを破棄すれば楽に完成版からデバッグ機能を無くす事ができる)

さて、実際にレベル分けを行った場合、次に必要になってくるのはレベルの読み込みタイミングの管理です。
そこでレベルの追加方法を確認しながら解説していきたいと思います。

まず、レベルウィンドウのレベルメニューから「新規作成」を選択肢し、新しいレベルを追加します。
1

この時追加した新規レベルは、そのまま実行しても読み込まれません。
これはレベルのデフォルトのストリーミング方法がブループリント制御になっているからです。
2

デフォルトのストリーミング方法

ブループリント ブループリントによって制御します
常にロード済み パーシスタントレベルを読み込んだ際、自動的に一緒に読み込まれます
読み込み方法は同期読み込みで、このレベルの読み込み及び表示が完了するまで、次のサブレベルの読み込みは発生しません

 

レベルを読み込むタイミングを決める

今回はブループリントによる制御で話を進めます。では、ブループリント制御にしたい場合はどんな時でしょうか。

  1. マップ遷移直後に該当レベルを非同期で読み込みたい場合
    すぐに必要のないレベルなどは非同期読み込みにすることで、マップ遷移時のロード時間を早める事が期待できます。
  2. 任意のタイミングでレベルを読み込みたい場合
    マップ遷移後すぐには必要ありませんが、ある特定のタイミングでレベルが必要になった時に読み込みたい場合です。

レベルの使用意図に合わせてこれらを使い分けます。
ちなみに1のパーシスタントレベルが読み込まれた際に自動で非同期読み込みを行いたい場合は、レベル詳細から設定できます。

変更したいレベルを選択し、レベルの詳細アイコンを押すと、そのレベルの詳細ウィンドウが開きます。

ほそく
3

Initially Loaded チェックマークを入れると自動で非同期読み込みを行います
Initially Visible チェックマークを入れると読み込み後に表示まで一緒に行います

今回は任意のタイミングでのレベルの管理を行いたいので、設定はそのままにしておきます。

 

任意のタイミングでレベルを読み込む

さて、では任意のタイミングでレベルを読み込む手段ですが、これはUE4だと2つ用意されています。

  1. Level Streaming Volumeを使用する
    ボリューム内にプレイヤーが侵入した場合に、指定されたレベルを指定した方法で読み込みます
    ボリューム外に出た場合はアンロードされます
  2. ブループリント内でLoad Stream Levelノードを使用する
    レベルブループリントなどで任意のタイミングに、引数のレベルを設定した方法で読み込みます
    ちなみにアンロードしたい場合はUn Load Stream Levelノードを使用します

まず1のLevel Streaming Volumeを使用する場合です。
このボリュームは少々特殊で、パーシスタントレベルに置くことでしか効果を発揮しません。
レベルの読み込みを管理するボリュームなので、必ず読み込まれるパーシスタントレベルに置くのは当然ですし、そもそも別のレベルに配置して設定しようとすると警告が出ます。
4

次に各サブレベルのレベル詳細で、対象となる配置したLevel Streaming Volumeを選択して紐付けます。
5

これでボリューム内にプレイヤーが侵入した際に、紐付けたレベルが読み込まれるようになります。
読み込み方法についてはボリューム側で設定できます。
6
Streaming Usage

SVB Loading 非同期読み込みのみ
SVB Loading and Visibility 非同期読み込み後レベル表示(デフォルト設定)
SVB Visibility Blocking on Load 同期読み込み後、表示完了まで待つ
SVB Blocking on Load 同期読み込みのみ行う
SVB Loading Not Visible 非同期読み込み後に非表示状態を保つ。Load Stream LevelやShould Be Visbleでも表示状態にならないので注意

次に2のブループリント内でLoad Stream Levelノードを使用する場合です。
この関数は処理待ちが発生するLatentノードなので、関数では使えません。使用する場合はイベント内やマクロで使用しましょう。

7

Level Name レベル名
Make Visible After Load 読み込み後に表示を行うかどうか
Should Block on Load 同期読み込みを行うかどうか

 

レベルの表示タイミングを制御する

さて、これでレベルの読み込み関連は一通り紹介しましたが、もう少し踏み込んでみましょう。
それはレベルの表示タイミングです。
レベルには、ロード済の状態でも表示状態と非表示状態の2種類の状態が存在します。
普段エディタで作業している時に、レベル単位で表示非表示を切り替える場合もあるかと思いますが、それと同じようにゲーム中にレベル単位で表示の切り替えが可能です。

ちなみにレベルウィンドウの各レベルの左横にある目マークのアイコンでどちらの状態か確認することができます。
8

ではレベルをロードするタイミングと表示するタイミングで分ける必要があるでしょうか?
メリットはあります。例えばメモリには余裕があるけど描画速度がキツイ…といった場合に有効です。
具体的にはある程度広いマップを使ったゲームなどが該当すると思います。
そこで背景レベルなどをいくつかに分割し、表示が必要でない箇所は非表示状態にしておけば、必要な時に素早く表示状態にできるというわけです。
似たような機能としてUE4にはWorldCompositionというオープンワールド用の機能が存在しますが、それを使わない場合はこういったテクニックを使うという選択肢も視野に入れてみてはどうでしょう。

話を戻しましょう。実際の実装方法としましては、二通り存在します

  1. Load Stream Levelノードを使用する
    引数のMakeVisibleAfterLoadをTrueにしておけば、レベルが読み込まれている状態に再度呼び出すと表示処理のみが実行されます。
    ただしこの方法だと非表示への切り替えできません。
  2. Get Streaming Levelを使用して直接Should be Visibleを設定する
    Trueにすることで表示状態にでき、Falseにすることで非表示状態にもできます。
    直接LevelStreamingのメソッドを触るのでちょっとプログラマ的には気持ちが悪いかもです。
    9

さて、このように表示タイミングを分けた場合、どうしても表示完了のタイミングを知りたいという状況があるかと思います。なぜならUE4のレベルの表示は一瞬で切り替わるものではなく、次第に表示されるような仕様になっているからです。つまり表示完了待ちというタイミング発生するわけです。
そこで指定レベルの表示が完了したかを調べる方法があります。

Get Streaming LevelからIs Level Visibleで判定を取る事が可能です。
10

これを実際に使える形としてマクロ化したものがこちらになります。
11

そして実際のマクロの使用例がこちらになります。引数を配列にすることで複数のレベルに対して同時に判定を行っていますが、その必要が無い場合はもっと中身は簡潔なもになるかと思います。
12

また、コンソールコマンドの「stat LEVELS」でもレベルの読み込み状況がリアルタイムに確認できるため、デバッグ時はこちらを積極的に活用していきましょう

このようにレベルの読み込みや表示タイミングを状況に合わせて自在に操れるようになれば、レベル管理も様々な状況で対応できるのではないでしょうか

 

おまけ

Level Streaming Volumeですが、ボリュームの設定方法としては他と違って少し特殊です。
レベル詳細の方で各ボリュームと紐付けるのはワークフロー的にちょっと…と思う方もいるかもしれません。
そんな時はボリュームクラスを基底クラスにブループリントを作成できるようにエンジン側を弄ることで、解消できるかと思います。

変数で対象のレベル名を指定できるようにします。
1314

ブループリントでボリューム内に入った時に対象レベルを読み込み(或いは表示)、出た時に破棄(或いは非表示)といった処理にすれば、他のボリューム配置と同様のワークフローで完結します。

15

[UE4] 任意の形状のボリュームを作る

$
0
0

今回は、任意の形状のボリュームやコリジョンなどを作成する方法を紹介したいと思います。

ゲームを作っていく上で、ダメージ床や特定の場所によるカメラの切り替えなど、侵入判定によって様々な挙動を変えたいときがあります。
そういった場合に役に立つのがトリガーボックスですが、それだとボックス型の判定しか取ることができません。ですが、トリガーボリュームを使う事で、ボックス型以外の形状で判定を取る事ができます。

UE4にはBSPブラシを自力で作成する機能があるので、今回はこれを使用します。

まずジオメトリの編集モードに切り替え、ペンを選択します。
1

次にビューモードをパースペクティブビューからトップビューに切り替えます
2

この際、自動でワイヤーフレームに切り替わるので、作業しやすいようにライティングなどに描画を切り替えます。
3

これでBSPブラシの作成が可能になります。
この状態で、任意の場所にスペースキーを押す事で、頂点が生成されます。
もし間違えた場合はバックスペースキーで頂点を取り消す事も可能です。
4

最後にエンターキーを押すことでBSPブラシが完成します。
5

次に作成したBSPブラシのアクターを選択した状態で、アクター詳細からConvertActorを選択します。
今回はトリガーボリュームに変換しますが、用途によって侵入不可用のブロッキングボリュームなど様々なボリュームに変換可能です。
7

※BSPブラシをConvertActorで変換した際、バグなのか変換前のBSPブラシがそのまま残ってしまいます。ですが、別のBPSブラシを作成したタイミングで、残っていた変換前のBSPブラシは削除されます。

これでBSPブラシによる任意形状のボリュームの完成ですが、これだけだと高さが合っていないと思うので、最後にZ軸をスケーリングなり移動させるなりして微調整しましょう。
ちなみに通常のBSPブラシ同様、後から各頂点の座標を編集する事も可能です。
8

後はレベルブループリントなどでボリュームに侵入した場合や出た場合の処理を書けば完成です。
※ボリュームもブループリント化できればもっと色々と用途を増やすことができるんですけどね…
9
10

[UE4] スプライン移動するキャラクターを作る

$
0
0

以前、スプラインの移動処理をコンポーネント化する方法をご紹介しましたが、今回はそのスプライン移動の機能を更に充実化させ、キャラクターを移動させる方法の一つをご紹介したいと思います。

 

ちなみに実装後の動画がこちらになります。

 

さて、前回までの機能は、移動処理にSetActorLocationAndRotationを使用していたため、キャラクターに使うには色々と問題がありました。例えば、スプラインを地面に添って設置しなければキャラクターが地面に浮いてしまったり、埋もれたりしてしまうからです。接地処理に関しては、キャラクターの足元からレイを飛ばして地面の座標を取得する方法などが考えられますが、毎フレームやるには処理が重いためあまり良い方法でありません。
そこでSetActorLocationAndRotationを使わず、移動処理のみをカスタマイズした新しいスプライン移動用のコンポーネントを作成したいと思います。

まずは準備として以前作成したコンポーネントに若干修正を加えます。
以前はTick内でForceMove関数を使用して移動させていましたが、強制移動とは別に通常移動用の処理を用意して、こちらを使うことにします。
そこで、新しく用意する通常移動処理の関数名をMovingProcessとします。

Functions

関数名 Description
MovingProcess 現在の移動量から通常の移動

MovingProcess関数

関数の中身は以前のForceMove関数と同じ処理を書きます。ただし、前回の移動関数には戻り値がありませんでしたが、今回はResultというBool型の戻り値を関数に追加します。これはこの後作る派生クラスで、移動関数をオーバーライド出来るようにするためです。

1

 

通常移動処理用の関数を用意したら、Tick内はこちらを使用するように差し替えます。

Event Tick

2

 

次に、スプラインを設定する関数であるSetSpline関数に機能を追加します。

SetSpline関数

引数に移動速度と、開始時にスプラインの始端へ強制移動するかのフラグを追加します。強制移動を行う際は、もちろんForceMove関数の方を使用します。

3

 

では早速新しくキャラクター用のスプライン移動コンポーネントを作成します。
まず、既存のスプライン移動コンポーネントを基底にした新しいコンポーネントを作成します。名前はとりあえずSplineCharacterMoveComponentとします。

4

次に基底クラス内の関数、MovingProcess関数をオーバーライドして関数を書き換えます。
この時、基底クラス側の関数に引数がないとオーバーライドした際に自動でイベント扱いとなるので注意して下さい。

5

6

使用したのはPawnのAddMovementInputです。Pawnの関数なので、オーナーをPawn型にキャストしています。
コンポーネントはどのブループリントクラスでも使用できるため、オーナーが必ずコンポーネント作成者の意図した型にならない事は注意して下さい。

これでキャラクター用の移動用スプラインコンポーネントは完成しました。
あとは実際にスプラインアクターをレベルに配置し、それをコンポーネントを追加したキャラクターが参照することで、スプラインに沿って移動できるようになります。

7

 

今までは移動処理の中身でスプラインの座標を直接取得していましたが、今回はスプラインの向き情報を利用してAddMovementInputでキャラクターを動かしています。ですので、移動速度に実際のキャラクターの移動速度を渡しておかないと、スプラインと実際の移動座標がずれてしまうのにご注意下さい。
また、開始時に強制移動を行っている理由も同じです。開始位置がスプラインの始端になっていないと、スプライン通りに移動する事ができないためです。通常移動と強制移動で処理を分けたのはこのためでした。

 

このようにやや癖はありますが、スプラインの向きのみを参照してキャラクターを動かしているので、凹凸の地面でも気にせずスプラインを引くことができます。わざわざ凹凸に合わせてスプラインを配置しなくても、キャラクターは勝手に凹凸に合わせて走ってくれるでしょう。
また、移動の処理自体はキャラクターのCharacterMovementの機能を使って動いているため、例えばOrientRotationtoMovementにチェックマークを入れれば、キャラクターは移動方向に合わせてそちらを向く事が可能です。

8

このように利点は大きいですが、やはりスプラインの座標を参照しているわけではないので、どうしても厳密にスプラインをなぞる事は難しいです。ですので、より正確にスプライン移動をしたい場合は、MovingProcessを自由にカスタマイズしてより正確なものを目指しましょう。

[UE4] Unityビルドシステム

$
0
0

今回は、UE4のC++ビルドシステムのオプションの1つである、Unityビルドシステムについてご紹介します。
某ゲームエンジンとは全くの無関係です。あくまでUE4のお話です。

また、C++についての知識を前提とした、プログラマ向けの内容になりますので、ご了承下さい。

 

今回の説明には、公式サンプルの1つであるShooterGameプロジェクトを使用します。
UE4公開初期からある、C++コードを使用したプロジェクトです。

 

まずは、さくっとこのプロジェクトをビルドしてみて下さい。
構成はデフォルトのまま、「Development Editor」でOKです。

ココで、ビルドログを確認します。

-------------------------------------------------------------------------------
Initializing...
--------------------Project: Default-------------------------------------------
PCH.ShooterGame.h.cpp (0:23.28 at +0:00)
Module.ShooterGame.cpp (0:15.18 at +0:23)
ShooterGame.generated.cpp (0:02.46 at +0:38)
ShooterGame.rc (0:00.09 at +0:40)
ModuleVersionResource.rc.inl (0:00.07 at +0:41)
UE4Editor-ShooterGame.dll (0:00.95 at +0:41)

こんな感じでビルドログが流れて、ShooterGameモジュールがビルドされているのが分かるかと思います。

 

ココで、1つ疑問が出てきます。
上記のログは、各C++ソースコードのコンパイルから、dllの生成までのログです。
しかし、ShooterGameプロジェクトに含まれている、多数のソースコードをコンパイルしている形跡がありません。

 

実は、ログのなかにある「Module.ShooterGame.cpp」に、このモジュール内の全てのcppファイルが含まれているのです。

 

どういうことなのか、確認してみます。下記のフォルダを覗いてみて下さい。

ShooterGame/Intermediate/Build/Win64/UE4Editor/Development/ShooterGame

unity_intermediate

ココは、ビルドのための中間ファイルが保存されるフォルダです。リンク前のobjファイルもココに配置されています。

先ほどのビルドログに出ていた「Module.ShooterGame.cpp」も見つかりました。
早速、中身を見てみます。

// This file is automatically generated at compile-time to include some subset of the user-created cpp files.
#include "中略\ShooterGame\Source\ShooterGame\Public\ShooterGame.h"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterEngine.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterGameDelegates.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterGameInstance.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterGameModule.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterGameUserSettings.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterGameViewportClient.cpp"
#include "中略\ShooterGame\Source\ShooterGame\Private\ShooterTeamStart.cpp"
//以下略...

ハイ、なかなかに恐ろしいですね。コレがUnityビルドシステムです。

リンク時間の短縮などの目的で、モジュール内のソースコードを全てincludeして、まとめてコンパイルしているそうです。

 

1つのモジュール内のソースコードが多い場合には、いくつかに分割されるようです。
UE4本体のソースコードをビルドした事があれば、ビルドログから下記のようなファイル名を見たことがあるかと思います。

Module.Core.1_of_7.cpp
Module.Core.2_of_7.cpp

 

UE4のC++ビルドでは、デフォルトでUnityビルドが有効になっています。
そのため稀に事故が起きてしまう場合もあります。

  • 必要なincludeを記述していないのに、コンパイルが通ってしまう
  • 無名ネームスペース内で定義した変数名や関数名が衝突する
  • 特定のコード内でしか使用しないつもりのマクロが、他のコード中でも反映されてしまう

といった場合には、ココを疑ってみても良いかもしれません。

 

Unityビルドは、必要であれば無効化することも出来ます。

その場合には、モジュールの .Build.cs に以下のように記述します。

BuildConfiguration.bUseUnityBuild = false;

この状態でビルドし、ビルドログや先ほどの中間ファイルの保存先を見てみると、各cppファイルが個別にコンパイルされていることが分かると思います。

 

下記のように書けば、DebugGame構成でのみUnityビルドを無効化する、といったことも出来ます。

if(Target.Configuration == UnrealTargetConfiguration.DebugGame)
{
BuildConfiguration.bUseUnityBuild = false;
}

 

Unityビルドが有効な場合、リンク時間が短縮される代わりに、少しの編集でもコンパイル時間が長くかかってしまうことになります。
状況に応じて使い分けると、少し快適に開発が出来るようになるかもしれません。

 

[UE4] Material Instanceで役立つUV座標のパラメータ化について

$
0
0

どうも、新人アーティストの渡邊です。
今回は、Material InstanceでTexCoodを使用する方法を解説したいと思います。

(Material Instanceのとってもわかりやすい解説はこちら

TexCoord04 TexCoord03

 

[TexCoord]とは、[TextureCoordinate]の略称です。
Coordinateは座標を意味します。このノードではUとV座標を指定し、タイリングすることができます。

 

Multiplyで繋ぎ、[ScalerParameter]を入力します。
これでMaterial InstanceでUVのタイリングが可能になります。
しかし、このままだとU座標とV座標に異なる値を入力することが出来ません。

TexCoord05

 

そこで、[ComponentMask]を使って、[TexCoord]からそれぞれの座標を抜き出してパラメータ化したいと思います。
[ComponentMask]は、指定したチャンネルをのみを出力するノードです。

TexCoord02
Rチャンネルを指定してU座標を出力し、一方ではGチャンネルを指定してV座標を出力します。
これを[Multiply]で繋ぎ、[ScalerParameter]を入力すれば、それぞれの値を変えることが出来ます。
[CompornentMask]で指定したチャンネルを追加しなければいけないので、[AppendVector]でチャンネル情報を戻します。

 

さて、Material InstanceにしてParameterを確認してみましょう。

TexCoord06

 

できてますね!
これでテクスチャを自由自在に伸び縮みできますよ!とっても便利!

よく使うのでファンクション化してみてもいいかもしれません。
参考にして頂ければ幸いです。

ScalerParameter以外のParameter表現式はこちら


[UE4] 名古屋 / 仙台 Meetup お疲れ様でした

$
0
0

名古屋 / 仙台 Meetup ご参加の皆様、お疲れ様でした。

 

第2回 UNREAL ENGINE4 名古屋 Meetup!! #ue4studynagoya
【UE4】Sendai Unreal Engine MeetUp! Vol.2

 

当日は両会場共に盛況だったようで、UE4の盛り上がりを感じています。
今年は昨年よりも更にこういったイベントが増えていくと思いますので、積極的に参加していけたらいいなと思います。

 

また、予告していました通り、名古屋での講演内容に関して公開致します。

 

 

スライド内にもありますが、こちらがデモ用の動画となります。
(当日は同内容をライブノーディングでご紹介しました)

 

開閉するドアを作るデモ動画

 

ぷちコンで使った各種機能の簡単なデモ動画

 

次回のぷちコンは春頃を予定しております。
興味のある方は是非ご参加下さい。

[UE4]マテリアル表現の幅が広がる!おもしろいノード&マテリアル関数集 1

$
0
0

UE4のマテリアルエディタでは、膨大な種類のノードやマテリアル関数を手軽に扱うことが出来ますが、

日常的に使うノードは案外限られているのではないでしょうか?

というワケで、今回は知って得する(かもしれない)おもしろいノードを幾つか紹介してみたいと思います!


 

Screen Aligned UVs

メッシュのUVに関係なく、スクリーン座標のタテを0~1,ヨコを0~1としてUV座標を取得できるノードです。
ScreenAlignedUV

↓”Texture Coordinate”でメッシュのUVを使用した場合と、”Screen Aligned UVs”を用いた場合の比較。
ScreenAlignedUV_Image

もちろん、こんな感じに組む事でタイリングを変更する事も可能です。

ScreenAlignedUV02

 


Texture Cropping

左上と右下のUV座標を指定すると、指定した範囲にテクスチャを縮小して表示する事ができるノードです。

TextureCropping01

 

複数のテクスチャを組み合わせればこんな事も。TextureCropping02


 Vector To Radial Value

UVを極座標に変換する事が出来るノードです。魔法陣等を作る時に便利です。

VectorToRadialValue


 Two Sided Texture

メッシュの表裏に別々のテクスチャを割り当てる事が出来るノードです。 ※”Two Sided”をオンにするのを忘れずに!

TwoSidedTexture

 

みなさんはいくつ使った事がありましたか?

[UE4] ネコぱらいぶ☆で使われた技術

$
0
0

先日のエイプリルフールに NEKO WORKs 様より公開されました「ネコぱらいぶ☆」にて、開発を担当させていただきました。

 

ネコぱらいぶ☆ 特設ページ
http://nekovr.club/

 

VRモード/非VRモードでの実行ファイルに加え、360度動画としても公開されております。
360度動画は こちら 。

 

コンテンツの内容に関しては 特設ページ を参照して頂いた方が良いかと思いますが、クオリティアップの為にいくつか技術的な試みを行ったので簡単に紹介させて頂きます。

 

ネコぱらいぶ☆で検証/実装した内容

ネコぱらいぶ☆は UE4.11 Preview7 で作られています。
本来は製品にPreview版を用いるのは良くないのですが、当初からエンジンを拡張して使用する構想があり、更にワークフローの主軸として検討していた シーケンサー について4.10版と4.11版をソースコードレベルで解析した結果、4.11の方が圧倒的に安定性が良く拡張しやすい作りとなっていたため、多少の懸念があったとしても4.11版で作っていった方がクオリティを出していけるという判断からです。
以下、ネコぱらいぶ☆で検証/実装した内容のリストです。

 

  • GDCでも目玉機能として紹介されたシーケンサーを用いた複数人並行作業
  • シーケンサーからマテリアルパラメータコレクションのプロパティ変更及びプレビューできるようにするエンジン拡張
  • AfterEffectsで作成したモーショングラフィックス用の連番ファイルをFlipbookで再生
  • 通常のライティングは行わず、トゥーンレンダリング用にマテリアルを構成し、照明と同期してキャラや背景の色を変える仕組み
  • InstancedStaticMeshを用いた軽量サイリウム描画
  • ShowDownデモで用いられたフェイクシャドウ(板ポリと減算マテリアルによる足影)
  • マテリアルパラメータコレクションによる複数SceneCaptureの切り替えと負荷対策
  • 半透明や加算、マスクを使用せず、どうしても必要な部分に関してはポリゴン化することによる負荷対策
  • スクリーンショット付きTwitter投稿機能
  • PNG生データを加工してロゴを上乗せする機能
  • 360度動画対応

 

こうやってリスト化すると結構ありますね…!
また、実装したけど今回は必要が無くなったのでオミットした内容として、「VR表示における安定した輪郭線描画手法」や「リミテッドアニメーション」というのもあったりします。
特筆はしませんが目線を合わせてカメラ切り替えや、3DサウンドといったVRに必要な要素も組み込んであります。

 

実作業的としてはそれほど長い期間を取ることができなかったのですが、ネコぱら自体がとても魅力的なコンテンツであったため、モチベーションも高く最後まで走り切ることができたプロジェクトでした。
今回はそれぞれ簡単にスクリーンショット付きでご紹介させて頂きます。
全てを細かく書くと長くなってしまうため、今回は紹介程度とします。
詳細な実装内容/手法に関しては追って別記事や講演の場等で発表させて頂ければと思います。

 

GDCでも目玉機能として紹介されたシーケンサーを用いた複数人並行作業

Nekopara_01

UE4を開発する Epic Games 様が GDCで発表された内容 の中に シーケンサー という機能があります。
これは主にデモ/カットシーン用のタイムラインエディタで、元々使われていたマチネに置き換わる新しいツールとして期待されています。
シーケンサーがマチネより優れている点としては、ざっと思いつく限りでも以下のものがあります。

 

  • サブトラックという名前で別のLevelSequenceアセットをタイムラインに乗せる事ができるため、複数人での作業が簡単になる
  • シーケンサーエディタを開いた状態でもゲームプレイを開始したり、保存することができる
  • キーを打つ作業がマチネと比べて直感的

 

ネコぱらいぶ☆はプログラマが一人、アーティストが一人、ピンポイントで何名かに少し手伝ってもらったくらいの少人数プロジェクトです
ただ、そんな中でもサブトラックの存在はとても大きく、各人の作業待ち時間をほとんど無くしてくれました。

 

 シーケンサーはいいぞ

 

 

シーケンサーからマテリアルパラメータコレクションのプロパティ変更及びプレビューできるようにするエンジン拡張

各マテリアルの中でグローバルに設定できるプロパティとして使えるマテリアルパラメータコレクションという機能があります。
こちらはとても強力で特に映像コンテンツを制作する場合には有効活用することで作品のクオリティを上げるために役立ちます。
ただ、標準機能ではマテリアルパラメータコレクションのプロパティをシーケンサー上からコントロールする機能が用意されていなかったため、エンジンを拡張して独自に実装しました。
上記動画ではシーケンサー上からマテリアルパラメータコレクションのプロパティ変更をプレビューできることが確認できます。

 

AfterEffectsで作成したモーショングラフィックス用の連番ファイルをFlipbookで再生

Nekopara_08

ネコぱらいぶ☆では演出の一つとしてモーショングラフィックスを組み込んでいます。
モーショングラフィックスは下記のように AfterEffects を用いて連番ファイルとして作成し、Flipbookを用いて再生しています。

 

Nekopara_06

AfterEffects の編集画面

 

Nekopara_07

出来上がった連番ファイル

 

通常のライティングは行わず、トゥーンレンダリング用にマテリアルを構成し、照明と同期してキャラや背景の色を変える仕組み

Nekopara_02

Nekopara_03

今回はUE4が得意とする物理ベースレンダリングを使ってもコンテンツに合わないため、背景の一部以外はライティングを行わずにマテリアル側でのパラメータ調整によりトゥーンレンダリングを実現しています。
この時にマテリアルパラメータコレクションを用いてキャラや背景等の別オブジェクトの色や明るさが同期されるようにもしています。
ちなみに最終的にシーン上からライトは完全に排除されました。

 

InstancedStaticMeshを用いた軽量サイリウム描画

Nekopara_04

今回はVR対応プロジェクトであり、できるだけ描画負荷を下げたいという目的があったため、大量のサイリウム描画には InstancedStaticMesh を使用しました。
上記画像では100本近くのサイリウムが表示されておりますが、MeshDrawCall はたったの 6 です。
しかし、StaticMeshなのでボーンを入れてアニメーション制御することはできません。
そのためマテリアル側で WorldPositionOffset を使用し、マテリアルパラメータコレクションからプロパティを制御することで、シーケンサー上からサイリウムの動きを付けられるように実装しました。

 

ShowDownデモで用いられたフェイクシャドウ(板ポリと減算マテリアルによる足影)

Nekopara_05

公開されている ShowDown デモの中で使用されているフェイクシャドウをネコぱらいぶ☆でも参考に実装致しました。
これにより影を表示するための描画コストを削減しています。
公式の解説ページは こちら になります。

 

マテリアルパラメータコレクションによる複数SceneCaptureの切り替えと負荷対策

マテリアルパラメータコレクションのプロパティから表示する元のRenderTargetを切り替えられるようにして、シーケンサー制御できるように実装しました。
これにより演出の調整がしやすくなっています。
ただ、SceneCaptureは描画回数が増えるため、描画負荷軽減のために必要のないものはキャプチャーしないようにする対応等も行っています。
また、プレビューでは合わせ鏡のように連続して写り込んでしまっている所も、再生時にはそうならないようにHidden設定を行って対応しています。

 

半透明や加算、マスクを使用せず、どうしても必要な部分に関してはポリゴン化することによる負荷対策

Nekopara_09

今回はフェイクシャドウによる足影以外では半透明や加算、マスクを使用していません。
上記はインゲームでのシェーダー複雑度ですが、シーン全体として単純化されているのがわかるかと思われます。
演出のクオリティは保ちつつも、できるだけパフォーマンスを向上させるために細かく調整してあります。

 

スクリーンショット付きTwitter投稿機能
PNG生データを加工してロゴを上乗せする機能

Nekopara_10

個人制作のプラグインですが、WebApiプラグイン でOAuth認証に対応し、スクリーンショット付きTwitter投稿機能を実装しました。
更に撮影したスクリーンショット(PNG形式)を投稿する直前にデータを直接書き換え、右下にロゴが上乗せされるようにしてあります。

 

360度動画対応

冒頭でも取り上げましたが、実行ファイルとは別にYoutubeにて360度動画を公開しています。
こちらは公開されているプラグインが不安定だったため、フォーラム等を参考に別のやり方で実装しました。
そちらも機会があれば公開していければと思います。

 

最後に

エイプリルフールネタとして終わらせるには勿体無いくらいのクオリティは出せたのではないかと思ってます。
短い期間の中でしたが、弊社からの要望や確認依頼を迅速に対応して頂けた NEKO WORKs 様にはとても感謝しております。
関係者の皆様、大変お疲れ様でした。

 

 ネコぱらはいいぞ

 

 

[UE4] 第5回UE4ぷちコン応募作品公開!その1

$
0
0

2第五回ぷちコン_バナー用

 

第5回UE4ぷちコンのエントリー作品一覧ページです。

応募いただいた皆様、ありがとうございます!!

応募作品過去最多!!第5回UE4ぷちコン応募作品一挙公開!

※コンテストの告知ページはこちらです。

・応募作品過去最多!!第5回UE4ぷちコン応募作品一挙公開!その2はこちら

・応募作品過去最多!!第5回UE4ぷちコン応募作品一挙公開!その3はこちら

 

 

[エントリーNo.1] Love Grayman

PaperSloth  さま

▼応募者コメント▼

立体起動的な動きでグレーマンを回避して
ステージに4体いるグレーマンを倒すとゲームクリアです。グレーマンにハートを当てると慈愛に満ちたピンクマンになります。
ピンクマン同士が衝突すると過剰な愛に耐え切れなくなって爆発します!
最後の1人になったピンクマンはプレイヤーの手で葬ります!

 

[エントリーNo.2] 愛を握り取れ

Takao  さま

▼応募者コメント▼

あなたは愛情を餌とする妖怪になって人間の愛を喰ってください。
モンスターの愛情表現は人間のそれとは違います。握りつぶしましょう。操作方法
Leap Motionのみ操作できます。
手をキャラクターに向けると赤い線が出ます。
赤い線が出ている時に腕を前に突き出すとキャラクターに手を飛ばせます。
そのまま手を少し握ってから手前に戻すと愛を奪うことができます。
拳を作ると握りつぶせます。
赤いハートは自分のものにして、
青いハートは握りつぶしましょう。クレジット
声 魔王魂 http://maoudamashii.jokersounds.com
斬撃音 ザ・マッチメイカァズ http://osabisi.sakura.ne.jp/m2/

[エントリーNo.3] ブルーとグレー 愛の劇場 春

もんしょ  さま

▼応募者コメント▼

  • UE4のアセットが愛によって生まれている、という事実を表現するためにこのゲームを作成しました。
  • とりあえず愛ってことにしてハートでも飛ばしておけばテーマに沿うだろう、などとは考えていません。
  • ええ、いませんとも。
  • [補足]
    今回は自前でモーションを作ることを目標にしましたが、やっぱりしょっぱいモーションしか作れませんでした。
  • でも、グレーマンの投げキッスは自分なりによく出来たと思っています

[エントリーNo.4] Dgame

FNBS  さま

▼応募者コメント▼

私が大好きなプログラミング言語のマスコットキャラクター『D言語くん』と『Lispエイリアン』を使用した作品です。
今までにないくらい(D言語くん、Lispエイリアンに対しての)愛を詰め込んだ作品です。彼らの愛らしい動きをぜひ味わってみてください。
[補足]
Lispエイリアンはpublic domain、
D言語くんはBoost Software License の下で使用しています。

[エントリーNo.5] アイノカタチ

Takayashiki さま

▼応募者コメント▼

このゲームはLeapMotionを使用してGrayちゃんと一緒にアイのカタチ(ハート)を作っていくゲームです。Grayちゃんと二人でアイのカタチを作ろう!!動画ではわかりにくい他の「愛(AI)」ポイントとして
①ハートの形はテクスチャ使わず「The Love Formula(愛の方程式)」を使って描画(多分、無駄に負荷が高い)
②ゲームの進行を一部BehaviorTreeを使って制御

[エントリーNo.6] 愛が冷めぬ間に

もんた さま

▼応募者コメント▼

•  シンプルなアクションゲームで、グレイちゃんが投げキッスで飛ばす
•  ハート(愛)を1分の制限時間内に多くとってハイスコアを目指します。
•  ハートは一度地面に付くと、どんどん冷めて青くなっていきます。
•  冷めきったら愛は怒りに変わり爆発します。
•  時間がたてばたつほど、投げられるハートの数は増え、愛で殺しにかかります。

[エントリーNo.7] ユニティちゃんのハート集め

荻野 雄季 さま

▼応募者コメント▼

ユニティちゃんがステージに散らばったハートを集める簡単なアクションゲームです。
開発者がユニティちゃん使用するのが大好き
なので、ユニティちゃんへの使用愛が詰まっています。

[エントリーNo.8] ドットイート(モンスターAI)

板庇 賢一 さま

▼応募者コメント▼

・モンスターに捕まる前にドットを食べ尽すゲーム

[エントリーNo.9] 姑から逃げるゲーム

姑から逃げるチーム さま

▼応募者コメント▼

嫁を操作し、姑から逃げきって、愛する家族を守るゲームです、制限時間内で逃げ切ればゲームクリア。今回「愛」というテーマでこのような設定にしました、あと「AI」というとらえ方で追跡のAIを挑戦しました。

[エントリーNo.10] AIの異常な愛情

蝋燭 さま

▼応募者コメント▼

製造段階で故障したAIはどういうわけか猫のオブジェに対し異常な執着を見せている。
このオブジェはとても大事なものなので彼から取り戻さなければならない!

[エントリーNo.11] ぱふぱふおいしくめしあがれ

ぱふぱふ さま

▼応募者コメント▼

飛んでくる肉まんをとるゲームです。愛=幸せを感じること、と考え私たちが幸せに感じるときは食べてる時とやわらかいものを触っているとき幸せだなと思うので、このような内容になりました。

[エントリーNo.12] angel

【OFTO-N】 さま

▼応募者コメント▼

テーマは「愛(AI)」なので
愛がこもった思い出のある品を探索して集める愛がこもってる作品です

[エントリーNo.13] 僕への愛はいつも空から落ちてくる

チシ さま

▼応募者コメント▼

中野シスターズのなかちゃんから送られてくる愛をキャッチするゲームです。
ウイルス フリー。 www.avast.com
彼女の愛に答えられるように、頑張って愛を受け止めましょう!
※愛がどのように降ってくるかは彼女の機嫌しだいです。

[エントリーNo.14] アイドルマネー 愛の錬金術師

たつのる さま

▼応募者コメント▼

街の人たちを金の力で愛に目覚めさせた後アイドルグループを結成し、即日ライブを開催。観に来てくれたファンからお金を荒稼ぎし
その荒稼ぎしたお金をつぎ込んで
本命のグレイちゃんを、特大の愛で目覚めさせよう

[エントリーNo.15] FIND HER

ちょむ さま

▼応募者コメント▼

ホラー風ステルスゲームです。ゾンビに攫われた彼女を助けに行くという「愛」要素に満ちあふれたゲームです。
ゾンビは決まったルートを巡回し、ゾンビの視界=前方120°の範囲にプレイヤーが入ると追いかけて来ます。また自分でドアを押し開けます。
まだステルスゲームの基本しか出来てないですが、将来的には音の要素や囮の要素も追加したいと思っています。

[エントリーNo.16] LieV

てんちょー さま

▼応募者コメント▼

「月がきれいですね」という表現をヒントにHTC Viveを使って部屋で寝っ転がって見れるものをと思って作りました。ついでにあの星座をなぞるとイベントが起きるようにしてみました。

[エントリーNo.17] Diving Night

やこふ さま

▼応募者コメント▼

愛する彼女の元へ夜這いしに行くゲームです。
両親に見つからないように彼女を探します。
彼女を見つけたらルパンダイブしてお楽しみタイム突入でクリアです。

 

[エントリーNo.18] 「ブルーマン、愛を掴み取れ」

なっつー (@yashinut) さま

▼応募者コメント▼

leapmotionを使って、ブルーマンを操作し、ハートを掴み取るゲームです。
ハートを取ると(最初は)かわいいボイスをかけてくれます。
また、ハートを取るとラブ度が変化し、ラブ度によって、ボイスが変化します。
たくさんのハートを掴み取って、愛に満たされよう!

[エントリーNo.19] ネイチャーサバイバル

alberobello/Dantelo and  fuyu さま

▼応募者コメント▼

今回のテーマが愛という事で、夫婦共同制作を行いました。
自然の中でマルチプレイ(愛の協力!)でサバイバルをすることが目的です。

[エントリーNo.20] アイムアイアイ

びきたろう さま

▼応募者コメント▼

ダジャレから着想し、テーマより動物愛護を訴える方向へ持っていきました。
UE作品っぽくないものを作るをコンセプトにスライドショーを作って入れてみました。
シュールな世界観とマウスオンリーのお手軽操作がウリです。
シリアルゲームの側面も持ち合わせています。
皆さんもアイアイの気持ちになってみてはいかがでしょう。
(制作期間2週間程度 個人製作)

 

・応募作品過去最多!!第5回UE4ぷちコン応募作品一挙公開!その2はこちら

・応募作品過去最多!!第5回UE4ぷちコン応募作品一挙公開!その3はこちら

[UE4] 360°動画の作り方

$
0
0

 

先月、ボーンデジタル様主催のセミナー(https://www.borndigital.co.jp/seminar/4163.html)で、ご紹介した360°動画の作り方をまとめます。

 

下記の動画がサンプルになります。

 

・大まかな流れ

SceneCaptureCubeを使用して、シーンをキャプチャし、Matinee/Sequencerから連番画像として出力します。

その連番画像を動画ファイルに変換し、Youtubeへアップします。

 

※補足事項

UE4の4.11バージョンから”StereoPanoramicMovieCapture”というプラグインが入っており、それを有効化することで360°用の連番画像を出力することも可能です。

20160412_01

 

 

 

ただし、現状ではアルファ版ということでGUI等もなく、コンソールコマンドから制御する必要があります。

また、実際に使ってみるとエラーにより上手くキャプチャできず途中で止まってしまうなど、動作が不安定であったため今回は使用を見送りました。

 


 

・SceneCaptureCubeのセットアップ

360°のテクスチャをキャプチャするためBluePrintを作成して、そのコンポーネントとしてSceneCaptureComponentCubeを追加します。

20160412_02

 

 

 

 

 

次に、キャプチャ画像のレンダリングのためにCubeRenderTargetというアセットが必要になります。

下記画像を参考にコンテンツブラウザより作成して下さい。

20160412_03

 

 

 

 

 

 

 

なお、CubeRenderTargetの解像度設定はアスペクト比[2:1]固定となっており、Size X 値が縦の長さになります。

下図のように2048に設定した場合はレンダリングされる解像度が4096 x 2048pxになります。

20160412_04

 

 

 

 

 

 

 

BluePrintへ戻ります。SceneCaptureComponentCubeを選択した状態で、Texture Targetに先程のCubeRenderTargetを設定します。

20160412_05

 

 

 

 

 

 

また、連番出力には直接使用しませんが、プレビュー用にCameraコンポーネントを追加しています。


 

・360°連番画像の出力設定

では、次にキャプチャした結果を連番画像として出力したいのですが、いくつか問題があります。

 

・SceneCaptureCubeからキャプチャしたCubeRenderTargetはそのままでは連番出力できない。

・CubeRenderTargetはHDRなためトーンマッピングなどポストプロセスが無効の状態で出力される。

・SceneCaptureCubeからRotationの変更ができず、CubeRenderTargetにはワールド座標で-Y方向に正対した画像がレンダリングされる。

 

これらの問題を解決するために、新たに画像レンダリング用のBluePrintを作成します。

20160412_07

 

 

 

 

 

 

内容としてはシンプルで、キャプチャ画像をマテリアルとして設定し平面に貼り付けてしまい、レンダリングするカメラの表示範囲をその平面と一致させるというものです。

そして、Matinee/Sequencerからそのカメラ画像をレンダリングする、という流れになります。

 

では、中身を見ていきましょう。

20160412_08

 

 

 

 

 

 

まず、CubeRenderTargetのアスペクト比[2:1]と等しい平面と展開されたUVを持つStaticMeshコンポーネントを追加します。

このメッシュに後ほどCubeRenderTargetをテクスチャとして使用したマテリアルを割り当てます。

 

次に、レンダリング用のCameraコンポーネントを追加します。

Camera Settings項で”Projection Mode”を”OrthoGraphic”に変更し、画角の影響を受けないようにします。

“Ortho Width”を先程のStaticMeshコンポーネントの幅と同じ値にして、”Constrain Aspect Ration”設定をオンにすることで、CubeRenderTargetと出力する画像を一致させることができます。

 

なお、マテリアルでCubeRenderTargetを使用する際の注意点ですが、下図のようにテクスチャをそのまま接続するとエラーが出ます。

20160412_09

 

 

 

 

 

 

 

 

そこで、Customノードを使用してUV値を加工します。

20160412_10

 

 

 

 

 

 

 

CustomノードにInputsをひとつ追加し”Input Name”を”UV”とします。

そして”Code”には

float2 Angles = float2(2 * PI * (UV.x + 0.5f), PI * UV.y);
float s = sin(Angles.y);
float3 Direction = float3(s * sin(Angles.x), cos(Angles.y), -s * cos(Angles.x));
return Direction.xzy;

と入力します。

 

※カスタムノードのコードとワークフローについては以下のフォーラムの記事を参考にさせて頂きました。

これで、”TextureCoordinate”ノードからUVをCustomノードのUVインプットへ接続することで、エラーが出なくなります。

 

さらには、Customノードに接続されたUV値を加算することで”CubeRenderTarget”を各UV方向にオフセットできますので、”SceneCaptureCube”の方向を回転させるように扱えます。

 

 

 

 

 

そこで、冒頭のキャプチャ用BluePrintのYaw値と紐付けるため”TextureRotation”というParameterを作りました。

このParameterをキャプチャ用BluePrintからDynamic Material Instanceを作って更新するようにすれば、プレビュー結果を簡単に確認できるようになります。

20160412_14

 

 

 

 

 

冒頭キャプチャ用BluePrintのEvent GraphでTickにより取得したYawの値を格納する変数”CaptureCameraYaw”を用意します。

20160412_12

 

 

 

 

 

 

一方で連番レンダリング用のBluePrintにオブジェクト変数を作り、キャプチャ用BluePrintを参照します。

20160412_13

 

 

 

 

 

 

 

これで準備が整いました!

 

では、レンダリング用のBluePrintにあるCameraを指定して、Matinee/Sequencerから連番画像として出力します。

今回は、Matineeを使用しました。

20160412_15

 

 

 

 

 

CubeRenderTargetで設定してある解像度と同じ4096×2048のPNG形式で連番出力しました。20160412_15

 

 

 

 

 

 

その後、出力された連番画像を編集ソフトやコンポジットソフトで動画に変換します。

 

最後にYoutubeのガイド(https://support.google.com/youtube/answer/6178631?hl=ja)にあるように動画ファイルにメタデータをつけます。

メタデータを含んだ動画ファイルをYoutubeへアップすると、自動的に360°動画としてエンコードされます。

 

ちなみに、先週のブログ(http://historia.co.jp/archives/4602)でもお伝えした「ネコぱらいぶ☆」(特設ページ )の360°動画も同様の方法で作成しています。

ご参考になれば幸いです。

Viewing all 989 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>