【UE4】ゲーム制作事例（The Rolling Ball）

[Unreal Engine 4 (UE4) Advent Calendar](https://qiita.com/advent-calendar/2017/ue4) 15日目の記事です。

ゲーム制作事例記事第２弾でございます。[第１弾はこちら](https://qiita.com/Dv7Pavilion/items/7528704910f52b4bfa78)。

「１週間ほどで出来るゲームを作ろう。モデルは全部基本形状で。ほんのり物理を感じるやつ。」という目標でゲームを作ってみました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ステージを傾けてボールを操り、ゴールを目指すゲーム。<br>作って気づいたが、自分はレベルデザインがとことん苦手みたいだ。<a href="https://twitter.com/hashtag/UE4?src=hash&amp;ref_src=twsrc%5Etfw">#UE4</a> <a href="https://twitter.com/hashtag/EpicFriday?src=hash&amp;ref_src=twsrc%5Etfw">#EpicFriday</a> <a href="https://t.co/PvPXc5q1AT">pic.twitter.com/PvPXc5q1AT</a></p>&mdash; PavilionDV7 (@Dv7Pavilion) <a href="https://twitter.com/Dv7Pavilion/status/921353425002029056?ref_src=twsrc%5Etfw">2017年10月20日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

スーパーモンキーボール風なゲームとなっています。

[ダウンロードはこちらから](https://paviliondv7.itch.io/therollingball)

#プレイヤーボールクラス
##ステージを傾ける
このゲームはボールを直接回転させてはおらず主にステージを傾ける事でボールを動かしています。これはプレイヤーボールクラスで行っています。
![2017-11-03_23h58_20.png](https://qiita-image-store.s3.amazonaws.com/0/104467/655f0b77-ea76-83b8-ec53-5072cd185924.png)
レベル上での階層はこのようになっておりBP_StagePvotと**ムーバブルに設定した**スタティックメッシュアクタを親子構造としています。プレイヤーの入力でBP_StagePvotを回転させることで**ステージを傾け**ています。
スタティックメッシュアクタはムーバブルに設定しておかないと一切回転してくれません。自分はこれに気付かず随分と時間を取られてしまいました。

![2017-11-04_00h09_43.png](https://qiita-image-store.s3.amazonaws.com/0/104467/cd53ed74-61c0-2dcd-b02c-0f661830655a.png)
ステージの回転処理部分です。WSキーを押したときにはピッチ回転（前後に傾ける）ADキーを押したときにはロール回転（左右に傾ける）としています。
しかし入力された数値をそのままSetActorRotationに入れてしまうとカメラの向きに関わらず常に決まった方向にしか傾きません。そこでカメラの前方と右方のベクトルから回転を作成し合成することでWキーを押した時はカメラの向いている方向にステージを傾けるようにしました。
この処理により**狙っている方向に転がれる**ようになり遊びやすくなりました。

##ボールを転がしやすくする
ステージを傾ける処理によりボールは転がり出しましたが**動き出しはゆっくりで転がり始めると中々止まらず**気持ちのよい操作感とはかけ離れた転がり方でした。
Massを0.0001kgと変更しても変わらずLinear DampingやPhysics Materialで摩擦の数値を小さくしてもほとんど変化しませんでした。
そこで物理設定の調整は早々に諦め、ステージの傾きによる回転に加えて更に**ボール自身にも回転を加える**ことにしました。
![2017-11-04_19h29_48.png](https://qiita-image-store.s3.amazonaws.com/0/104467/fa52e510-9d47-e734-158d-b0635372b4e8.png)
ステージを傾ける処理と同様に**カメラの前方と右方のベクトルにトルク量と入力量を掛けて**AddTorqueしています。
これにより重たい金属玉が木製の玉くらいには軽く良い感じに転がってくれるようになり、より大きく操作性が向上しました。

>*画像ではAddTorqueにWARNINGが付いていますがUE4.18で非推奨のノードとなったためです。推奨版は以下になります。
![2017-11-04_19h50_29.png](https://qiita-image-store.s3.amazonaws.com/0/104467/424c3796-7871-8acb-4025-26aad2fbd75c.png)*

#フェードインアウト
ゲーム中のフェードインアウトはUMGを使っています。
![2017-11-04_22h58_08.png](https://qiita-image-store.s3.amazonaws.com/0/104467/f5c8cce1-c81e-24b0-7e99-250d26dbc67f.png)
イメージパネルを画面を埋めるサイズに調整し、アニメーションでカラーを変更しています。
![2017-11-04_23h01_18.png](https://qiita-image-store.s3.amazonaws.com/0/104467/ece042fa-8610-db71-c47c-d4e777e0f7b1.png)
あとは呼び出したいタイミングでフェード再生関数を呼び出せばフェードインアウトさせることが出来ます。フェードインのアニメーションを作りフェードアウトの場合は逆再生すると必要なアニメーションは１つだけになりますので少し楽に実装できます。

![2017-11-04_23h11_34.png](https://qiita-image-store.s3.amazonaws.com/0/104467/3c475b81-22ce-2512-7f9e-721810f13515.png)
PlayFade関数でウィジェットアニメーションを返り値としていますが、こうすることで呼び出し側でアニメーション終了時のディスパッチャイベントを定義出来るので**「フェードアウト後にシーン遷移処理を呼ぶ」**という一連の流れが書きやすくなります。

#3,2,1,GO!
ステージ開始時はカウントダウンされ「GO!」のテキストと同時に始まります。
この機能はSet Timer by Eventを使って実装しています。
![2017-11-04_23h37_13.png](https://qiita-image-store.s3.amazonaws.com/0/104467/6047acf0-37cc-b4c6-fb5b-867ebfc31dbe.png)
１秒毎にCountDownイベントが呼び出され「GameStartRemainTime」を減らしています。これが0以下になった時に「GO!」の表示とカウントダウン表示テキストをHiddenにしています。
しかしこのままではカウントダウンは終了したのにも関わらずCountDownイベントは１秒毎に呼ばれ続けます。ですのでSetTimerByEventから取得したTimerHandleを以下のようにClearすることでSetTimerByEventを停止させています。
![2017-11-05_00h27_21.png](https://qiita-image-store.s3.amazonaws.com/0/104467/c5075120-6127-cd7a-d5ff-aa62da6cd833.png)

#ステージ作成
ステージ１以外は**BPSブラシからスタティックメッシュ作成機能**を用いてステージを作成しています。
この機能はDCCツールを使わずエディタ内で作業が完結するのでテストレベルを作成するのにはうってつけの機能です。自分がモデリングをする際に使用しているBlenderでは扱うスケール単位が異なるため製作したモデルをインポートした時「あれ？思ってたより小さい（大きい）」となることが多々あります。この機能によりエディタ上で作業が完結しますからサイズ感の確認もしやすくインポートや再インポート等の作業がゼロになるので試行錯誤しやすくなります。

複数のBSPブラシからスタティックメッシュを作成する手順は以下のようになります。
![2017-11-05_23h13_34.png](https://qiita-image-store.s3.amazonaws.com/0/104467/c4554d68-0041-d488-a1cc-74164362f00b.png)
この時**最後に選択したBSPブラシの中心がメッシュの原点になる**事に注意してください。
BSPブラシを配置した時点でマテリアルを適用しておけば**そのマテリアルが適用されたままスタティックメッシュが作成される**のでここも注意点です。


#おわりに
物理演算の設定は当初想定していたよりも多くの時間を取られました。狙ったとおりの挙動（転がり方等）をさせるのが難しく最終的にはBlueprintで補正するような形になってしまいましたが望んでいた操作感は実現出来たので良かったかなと。これを機に物理周りはしっかり勉強したいと思います。

BSPはやはりプロトタイプにはかなり有用ですね。ブラシからメッシュ生成も**ブラシを組み合わせた複雑な形状**からもメッシュが生成出来ますので今回のプロジェクトでは大助かりでした。

明日は[もんしょ](https://twitter.com/monsho1977)さんによる[『UE4の描画パスの流れを4.18バージョンにアップデートしたい』](http://monsho.hatenablog.com/entry/2017/12/16/012502)です！