GameProgrammar's Night

ゲームプログラム系の覚え書き

UnrealEngine4で2Dゲームを作ろう! その12 プラグインをソースからビルドする

 JoystickPluginについて書いていたんですが、その前章としてプラグインのビルド方法について書きます。
 対応バージョンは、UE4.10です。

VS2015をインストールする

 まずは、UE4.10で対応となったVS2015をインストールする必要があります。

 DL先は、「Visual Studio 2015 製品の概要」。これのCommunity版を落としてインストールします。
 デフォルト設定では、VC++がインストールされませんので、カスタムを選択して、プログラミング言語→Visual C++のインストールにチェックをいれてください。

f:id:katze_7514:20151116173341j:plain

 それ以外の項目は、UE4だけで使うなら必要ありませんのでチェックを外しても大丈夫です。

UEプロジェクトのC++プロジェクトを作る

 すでにUEプロジェクトでC++を利用している場合は、C++プロジェクトは作成済みですので、この項目は飛ばして下さい。

 BPオンリーで作業をしていると、C++プロジェクトがありませんので、まずはそれを作ります。

1.エディタのファイルメニューから、「新規C++クラス...」を選択

f:id:katze_7514:20151116184050j:plain
 

2. 親クラスはNoneのままで、[次へ>]を押す

f:id:katze_7514:20151116185400j:plain

3. 何もせずに[クラス作成]

f:id:katze_7514:20151116185624j:plain

 すると、C++のプロジェクトが作成され、最初のコンパイルが始まりますのでコンパイルが終わるまで待ちます。
 コンパイルが終わるとVisualStudio(以下VS)が立ち上がります。

4. 立ち上がったVisualStudioから、3で作ったクラスを消す

f:id:katze_7514:20151116190155j:plain

 ソリューションエクスプローラから、MyClass.h/cppを削除します。C++プロジェクト作成ためだけのダミークラスですので必要ありません。
 削除したあとは、VSを閉じます。「保存しますか?」的なダイアログが立ち上がりますので保存します。
 また、VS上からは消えてもファイルの実体は残ってますので忘れずに消しておきます。C++プロジェクトを追加すると、UEプロジェクトのフォルダにSoruceというフォルダが生成されます。その中に入っています。

f:id:katze_7514:20151116191308j:plain

プラグインのソースをプロジェクトに追加してビルドする

1. UEプロジェクトに[Plugins]というフォルダを作り、そこにプラグインを入れる

f:id:katze_7514:20151116191016j:plain

 UEプロジェクトを作ったばかり時には、Pluginsフォルダはありませんのではじめてプラグインを導入する時はフォルダを作ります。
 なお、[Plugins]と複数形です。

2. UEプロジェクトのファイルを右クリックし、[Generate Visual Studio Project Files]を選択

f:id:katze_7514:20151116192104j:plain

 プラグインが正しく配置されていれば、C++プロジェクトにプラグインのソースファイルが追加されます。

3. UEプロジェクトのソリューションファイルをダブルクリックしてVSを立ち上げて、ビルド

 プロジェクトファイルの近くにある[プロジェクト名.sln]のファイルがソリューションファイルです。

 f:id:katze_7514:20151116192839j:plain

 Win64にして、DebugGame Editor/Development Editor の2つでビルドすれば完了です。
 プラグインのビルドは、UEエディタ上でのコンパイルボタンには対応されてないようなので、VS上でビルドする必要があります。プラグイン側が対応していれば、ホットリロードも効きます。

UnrealEngine4で2Dゲームを作ろう! その11 見下ろしマップの回り込み処理

 たまには「2Dゲーム作ろう!」らしいネタで、キャラクターとマップ上のオブジェクトとの描画順をどうするのかというお話です。

回り込み

 回り込みという表現はサークルローカルかもしれないので、実例のgifアニメが下の通り。(マチネででっち上げたので歩きアニメになっていのはただの手抜きですw)

回り込み処理 あり 回り込み処理 なし
f:id:katze_7514:20151029181036g:plain f:id:katze_7514:20151029181012g:plain

 像の周りを回った時に、キャラクターの位置に応じて像の前後にグラフィックが表示されるかどうかということです。
 3Dだと奥行き情報をモデルやコリジョンが持っているので特別考える必要はないのですが、2Dだと相変わらず自前で処理する必要があります。とはいえ、内部的には3D処理されていますので、奥行き軸(見下ろしの時はZ軸、サイドビューの時はY軸)の値を変更するだけで対応ができます。

奥行き値の計算

 見下ろしの場合は画面下方にあるほど、画面手前にきますので、Y座標をZ座標にコピーしています。
 
f:id:katze_7514:20151029183957j:plain

 あとで、ある程度調整ができるように基本Z値を指定できるようにしてあります。
 AdjustZ関数のScene引数はSceneComponentのことで、本ゲームではPaperFlipbookComponentを引数に渡しています。移動を行うActorはこの関数を適切なタイミングで呼んでいます。
 回り込みはグラフィックだけで良いのでActor自体のZ値は書き換えません。ActorのZを書き換えてしまうとコリジョンがめんどくさいです。

 この計算だとマップが広いとカメラのZ値を超えてしまうこともあるので、カメラのZ値はかなり大きい値を入れておきます。
 また、マップ上の静的スプライトもこの計算式を念頭に置いたZ値をPaper2Dのコンポーネントに入れておきます。

奥行き計算アルゴリズムとソート軸

 この辺の処理を作っている時に見つけたのですが、奥行き計算をどうするのかという設定が、プロジェクト設定にありました。
 [プロジェクト設定]→[Rendering]→[透過性] です。

f:id:katze_7514:20151104165220j:plain

 見下ろしマップの場合は上図のように設定すると良いと思います。

項目 意味
Translucent Sort Policy 奥行きソートのアルゴリズム。[Sort Along Axis]は指定軸の値に依存する。2Dゲームの場合はこれで十分です
Translucent Sort Axis アルゴリズムを[Sort Along Axis]にした場合のソート軸。見下ろしの場合はZ軸になりますので、(x, y, z)=(0.0, 0.0, -1.0) と値を入れておきます。

DirectXゲームの動画キャプチャ事情

 このデモをUE4上で作り終わったあとに動画キャプチャをしようと思ったのですが、愛用していたFrapsがまともに動かなくて困ったんですよねー。1分ぐらい録画すると途中から見られない動画ができ上がる始末。
 Fraps自体は大分前に更新が止まっていて、Win7 DX10までの対応で終わってるからみたいでした。というわけで、新しく動画キャプチャ環境を探さないといけないんですが、何か良いのないですかね?
 とりあえず、手元ですぐできるWin10付属のGameDVRかShadowPlayかって所ですが、GameDVRは60fps撮影ができないのでShadowPlayに落ち着きそうではあります。
 ついでにUE4での録画についても調べたので、書いておきます。

UE4での録画

 UE4での録画には、2種類あります。

マチネのムービーボタン

 マチネのウインドウを開くと、右上にムービーボタンがあります。押すとダイアログが出ますので、適当に設定してOKボタンを押すとゲームが起動してビデオキャプチャをはじめます。

f:id:katze_7514:20151029021346j:plain

 キャプチャされた動画は「プロジェクトファイルがあるフォルダ/Saved/VideoCaptures」に出力されます。
 無圧縮AVIなのでアホみたく容量を食います*1が、お手軽です。しかし、ゲームの撮影には致命的な問題があり使い物になりません。

 UMGが撮影されません。
 カメラで見えてる部分のみの撮影になるようで、カメラの上から描画されているUMGはキャプチャされません。

起動引数「-DUMPMOVIE」

 パッケージ化したあとのexeに、起動引数として「-DUMPMOVIE」をつけると1フレごとに連番スクショを出力します。撮影後に動画作成ソフトで連番スクショを動画化します。
 この場合は、可変フレームレートだと安定して撮影できない(スクショを吐き出す負荷でフレームレートがかなり下がります)ので、合わせて起動引数に「-BENCHMARK -FPS=60」などとしてフレームレートを固定すると良いと思います。
 こちらはプライマリバッファ(フレームバッファ)をスクショにしますので、UMGも問題なく撮影されます。
 1フレごとにファイルに書き出しているので時間が掛かるのと、無圧縮AVIまでは行きませんがHDD容量をかなり食いますので、余裕のある時にしか使えません。

ShadowPlay

 というわけで、ShadowPlayに落ち着くわけです。
 ShadowPlayは、nVidia製のGPUで使えるキャプチャソフトでGPU内でキャプチャしてエンコードするので、CPU負荷がほぼなくShadowPlayを実行しながらゲームをプレイするのも問題ありません。そのため、自動プレイキャプチャだけでなく実際にプレイしながらの画面も十分に撮ることができます。画面サイズやフレームレートの制限もありません。
 ただし、ウインドウモードには対応してないのとGPUGeforce縛りになります。

 UE4だとフルスクリーン実行も簡単なので、もうこれで良いかなと思っております。UE4アプリのフルスクリーン起動は、ゲーム内コマンドラインで「r.Res=1280x720f」という感じで画面サイズの最後にfをつけるか、起動引数に「-FULLSCREEN」をつけることでできます。

*1:ファイルが大きすぎて再生してもロードが追いつかず再生フレームレートが落ちるぐらいでかい。90秒で18GB

UnrealEngine4で2Dゲームを作ろう! その10 マチネでデモ

まずは、こちらをご覧下さい。

現在制作中のゲームのデモになります。
10/25のイベント向けに作ったもので、マチネを利用して作りました。

マチネ

 マチネは、UE4上でカットシーンを作るための機能でタイムラインを使ってActorに動きをつけることができます。
 基本的な使い方は、公式ドキュメント「マチネ & シネマティクス | Unreal Engine」やhistoriaさんの「[UE4] Matineeでカットシーン制作(1) Actorを登録して動かしてみる | historia Inc - 株式会社ヒストリア」を参考にして頂くとして、ここではケーススタディを書きたいと思います。

マチネの大切な仕様

 マチネでカットシーンを作る上で重要な仕様がいくつかあります。

マチネ実行中でも、ActorのTickなどは通常通り動作している

 PIE実行してBPのデバッグ表示を見れば一目瞭然なのですが、ActorのTickやEvent動作はマチネ実行とは独立して実行されています。
 そのため、あるActorはマチネで動かして、あるActorはAIで動かして、あるActorはユーザー入力で動かすなど、すべて混ぜて使うことができます。

 この仕様は、元Flasherの自分にはかなり嬉しくて、マチネとBPを混ぜ合わせて作ることで大分早く作れたかなと思います。

マチネで設定しているパラメータは絶対である

 ActorのTickなどで値を操作していても、マチネ上で設定されているパラメータに強制的に上書きされます。1つのActorをマチネとBPの両方で操作している場合に顕在化するので、気をつけましょう。

 地味にハマリました……。

キーフレーム間の補間処理を切ることができない

 キーフレーム間は必ず補間処理が走ります。そのため、ある時間帯はActorのTickに任せて、また時間がきたらマチネの管理に戻すということはできません。

 補間を切りたい時だけ、Pauseすればいいんじゃないか? とも思いましたが、マチネ全体が止まってしまうのでそれはそれで困るという結果に。

操作できるActorは、レベルに配置されているもののみ(アウトライナに存在しているActorのみ)

 SpawnしたActorをマチネの対象にすることはできません。また、PlayerControllerのような実行前に実体がないActorも対象にできません。
 できてくれるとかなり使い出あるんで、そのうちできるようになったりしないですかね。

以上のことを踏まえて、今回作成したデモは、以下のような構成となっています。

今回は、記事が長いのでここで折りたたんでおきます。

続きを読む

UnrealEngine4で2Dゲームを作ろう! その9 BPでのインスタンス(オブジェクト)生成

 BPで各種インスタンス(オブジェクト)の生成についてのまとめです。
 newとかプログラマになじみのある用語は使われておらず、調べるのにちょっと苦労したので備忘かねてます。

リテラルや構造体は「Make ***」

 即値や構造体は、Makeではじまるノードです。

f:id:katze_7514:20151015220831j:plain

Actor(を継承したクラス)は、「Spawn Actor from Class」

f:id:katze_7514:20151015221640j:plain

 生成と同時にLevelに配置されます。
 LevelやActor(を継承したクラス)上でしか呼び出すことができません。

 サウンドやパーティクルなど、専用のSpawnノードが用意されてるシステムもあります。

 破壊は、DesytroyActorノードになります。

Componentは、「Add *** Component」

f:id:katze_7514:20151015222051j:plain

 ComponentはBPエディタなどで固定でつけることが多いと思いますが、上記のノードで指定したActorに追加されます。

 破壊は、「Desytroy ***」ノードです。

Object継承クラス(Actor以外のクラス)は、「Construct from Class」

f:id:katze_7514:20151015221639j:plain

 4.9から、Actorを継承しないクラス、つまりObjectを継承したクラスもBPでインスタンス生成ができるようになりました。(前バージョンまではC++を介す必要がありました)
 Object継承クラスは、構造体では物足りない機能を持ったデータクラスを作るなどに利用します。
 現在、個別に破壊するノードはなさそうですので、リファレンスを外してGCに任せるだけになるみたいです。

 Actorを継承していないクラスのハマりポイントとしては、使用することのできるノードに一部制限が掛かることです。SpawnActorなどLevelに関するノードが使うことができません。ソースをざっと見ると、Actorが持っている情報を暗黙に使っているためのようです。他にもあるかもしれませんが、自分が一番ハマったのはそこでした。

それ以外

 Widget/Materialは、「Create ***」あたり。