気づけばツール漬け

3D,2Dのツールを色々使ってみた記録を書いていきたいです。

「ぷちコン★ENDLESS RUNNER 未知の生物もいるよ」制作メモ

f:id:mi-zmix:20210928202529p:plain

はじめに

「ぷちコン★エンドレスランナー 未知の生物もいるよ」の制作メモです。
今回使用したUE4は、4.26.2です。作っている途中で4.27が出ましたが、アップデートは見送りました。
テーマが道ということで、色々悩みました。最初はタワーディフェンスのような感じで、道をプレイヤーが自由に作り固定砲台の場所まで敵を誘導するという感じのを考えていたのですが、いまいち面白くならなかったのでやめておきました。(自由ってほど自由にならなかったし、砲台が固定なら結局最適な誘導ルートって限られてくるので)

他にいい案が思い浮かばなかったので、ぷちスタのエンドレスランナーを作ることにしました。ぷちスタは、課題のクリアを目指して作業していけばいいので、とてもやりやすかったです。課題にない他の要素はとりあえず後回しにして良いので、気持ちがとても楽でした。

 

応募動画はこちら

www.youtube.com

 

パッケージ化したものを置いておきます。
出所不明のアプリと怒られると思いますが、詳細をクリックすることで開けるようになるはずです。

drive.google.com


 

コースについて

ロブさんのエンドレスランナーのチュートリアルはとても助かりました。これがあったから作れたと言っても過言ではありません。エンドレスランナーは、コースを無限につないでいく方法と、いらないコースを消す方法が最重要項目だと思うので、この作成方法が知れるのは大きいです。

www.youtube.com

一度チュートリアルと同じように進めてみましたが、コース幅が広すぎと感じたので狭くしました。横の移動はフリーなのですが、レーン切り替えっぽい見た目になるように調整しました。3列のレーンぽくすることで、前から迫ってくる障害物を識別しやすくなったと思います。

横移動は自由にできるので、序盤で勢い余って落ちないように壁をつけておきました。横の壁の上も走れます。壁の上を走ってもあまり良いことはないですが。

 

コースアクターの構造

まずベースのコースアクターを作って、その子アクターでバリエーションを作りました。

コースの長さは1000cmにして、1レーン分の幅のメッシュとサイドに置く白線のメッシュで分けて、組み合わせるようにしました。アクター内でメッシュを並べるのは少し面倒ですが、メッシュモデルを作る工程は無駄が無いので楽です。

f:id:mi-zmix:20210927205520p:plain

前方に、コースアクターを消すためのコライダを置きました。ここをプレイヤーが通過したときに、自分アクターを消します。地面の下にあるのは、落下を判定するためのコライダーです。プレイヤーキャラがオーバーラップしたらゲームオーバーになります。

コースアクターのスポーンはゲームモードで行いました。自分が消える直前に、ゲームモードへ通知して次のコースアクターをスポーンさせる流れです。

f:id:mi-zmix:20210927205759p:plain

ゲーム開始時に7個分を先にスポーンさせておき、8個目のスポーンから、エンドレスの流れにしました。コースアクターをスポーンした直後に一番うしろのコースとして変数に格納しておき、そのコースアクターからインターフェイスを使って接続位置のトランスフォームを受け取る流れです。

f:id:mi-zmix:20210927210019p:plain

障害物やコインの出現はロケーションをランダムにせず、アローコンポーネントを使って決まった場所に設定し、その中でランダムに抽選されるように設定しました。設定がちょっと面倒ですが、ジャンプ距離とか避けるタイミングとかを考えて難易度設定ができるので、この形にしてよかったと思います。各ポイントを配列にまとめて、Random Integer In Range で選択するようにしました。下図は木箱配置用の関数の中です。

f:id:mi-zmix:20210927210705p:plain

障害物である木箱は、前方にだけオーバーラップ用のコライダーを置きました。これによって前から当たったときだけゲームオーバーになるようにしました。メッシュのコライダーはブロックにしてあるので、ぶつかりはしますがゲームオーバーにはなりません。横移動はフリーに動けて細かく避ける調整がしにくいので、横からぶつかっても大丈夫にしました。

f:id:mi-zmix:20210927210912p:plain

 

プレイヤーが獲得したデータの流れ

プレイヤーのコイン獲得数と走った距離はゲームステートで管理しました。距離はプレイヤーキャラ内で計算して随時ゲームステートに送るようにしました。なのでTickで動いてます。最初はコースアクターにつけたコライダーの通過で10mごとに計測していましたが、もっと細かい数値になるように計算になおしました。Tickからの流れなので、ゲームのスタートとゲームオーバー時にせき止めるためにGateを置いてます。

f:id:mi-zmix:20210927211238p:plain

計算の関数の中は、以下の図の感じです。

f:id:mi-zmix:20210927211351p:plain

コインの取得数は、ゲームステートで加算して確保しておきました。コインから、プレイヤーキャラに拾われた通知をゲームステートに送って、ゲームステートの変数に加算しました。プレイヤーキャラはコインの合計獲得数を知りません。

f:id:mi-zmix:20210927211645p:plain距離とコイン獲得数の値は、ゲームステートからプレイヤーコントローラーへおくり、そこからWidgetに表示するようにしました。

f:id:mi-zmix:20210927211819p:plain

f:id:mi-zmix:20210927212213p:plain

ゲーム内で表示するWidgetは、全部プレイヤーコントローラーでクリエイトすることにしたので、ちょっと回りくどいですが、ゲーム中に表示するためのデータはプレイヤーコントローラーを経由する流れにしました。

f:id:mi-zmix:20210927211928p:plain

今回のゲームは、プレイヤーキャラがどうにかなればゲームオーバーになるのでシンプルでした。時間切れやゴールなどの条件がないので、ゲームオーバーはプレイヤーキャラの中で処理しました。ゲームオーバーになったあと関係各所に通知を送るのですが、回りくどくしたおかげで通知の数と流れはわかりやすくなりました。

f:id:mi-zmix:20210927212633p:plain

ゲームステートは、ゲームオーバーになった通知でリザルト用のスコアを計算してから、最終データとともにゲームインスタンスへセーブするための通知を送りました。

f:id:mi-zmix:20210927212915p:plain

リザルトの表示はプレイヤーコントローラーが、ゲームインスタンスからデータを引っ張ってきて、リザルトWidgetに渡すようにしました。

f:id:mi-zmix:20210927213152p:plain

猫神(マグネット)について

エンドレスランナーでは、割とおなじみの仕組みであるマグネットを入れてみました。周囲のアイテムを自動的に引き寄せてくれるやつです。

限られたところに出現させるため、いくつかのコースアクターの中にアローでポイントを置いて、それぞれのコースアクター内で出現させるためのランダムの数値を調整しました。

f:id:mi-zmix:20210927235846p:plain

GetRandomFloatValue関数は、関数ライブラリ内につくったもので、中でRandomRangeでfloatの0~1の値を設定しています。出現用の値は低めに設定したつもりですが、出るときはわりと偏って出てくる気がします。

f:id:mi-zmix:20210928000044p:plain

猫神をとったあとのプレイヤー側は、半径が大きいスフィアトレースを使って広い範囲をトレースし、1個ずつ引き寄せるようにしました。最初は0.01秒間隔のタイマーで動かしていたのですが、ほとんどTickの間隔と変わらないので、Tickで動かすようにしました。0.01秒くらいの時間じゃないと、取りこぼしがあったので短くしました。

f:id:mi-zmix:20210928204458p:plain

プレイヤーのスフィアトレースにHitしたコインに、インターフェイスでメッセージを飛ばし、コインがプレイヤーに寄っていく動きにしました。引き寄せる動きは、Vinterpを使いました。Timelineを使って、Z方向に少し持ち上げる動きも入れました。

f:id:mi-zmix:20210928000545p:plain

猫頭は、単純にソケットの位置でチャイルドにしてしまうとアタッチした瞬間のロケーションだけ合わさり、以降のロケーションはそのままで本体の微妙な動きについてきてくれなかったので、AttachComponentToComponentでくっつけました。猫神さまはアクターなので、ローテータームーブメントを入れて常に回るようにしました。

f:id:mi-zmix:20210928000912p:plain

コースに置いた猫神さまと、アタッチする猫神さまは別物にしました。Z軸の回転方向が180度違います。結局回転してるので同じようなものなのですが、アタッチ直後にカメラ方向を向いてると微妙に気持ち悪かったので反転させました。あとスケールも道に出現するものとアタッチしたもので違う値にしたので、2つの状態に対応させるより分けたほうが楽だとおもったので分けました。

敵(未知の生物)について

障害物が木箱だけだと、ミスすると思えないほど緊張感も変化も乏しかったので、なにか違う障害を置こうと思って作りました。ふと目にとまった「ぷちコンのキービジュアル」のやつらを3Dモデルにしてしまおうと思い立ち作りました。

道路の横に立ってる「飛び出し坊や」みたいな感じで、平面的なイメージにしました。動きも平面的に横に倒れてくるだけにしておきました。目の部分をくぼませて、こっちを見ている感じにしてみました。高速で通り過ぎるので、ほとんどわからないのですが・・・

f:id:mi-zmix:20210928001409p:plain

横に倒すのは、Rinterpを使いました。Rinterpで回して、ClampAngleで止めておく感じです。図はぷちスタ用に急いで作業した状態のままですが、右用と左用でコピペしてざっくり作りました。

f:id:mi-zmix:20210928001757p:plain

f:id:mi-zmix:20210928001925p:plain

細長いスフィアトレースを両側に出して、プレイヤーを検出しました。トレースの半径や長さはタイプごとに変えました。紫のやつと黄色のやつは、倒れ込む直前にスケールをかけて少し大きくしています。ハードモードになってからは、わざと検出させてからジャンプでかわしたり反対側を通ったりするテクニックが重要になってきます。

f:id:mi-zmix:20210928204901p:plain

未知の生物を入れたことで、コースに変化が出て緊張感も出るようになったので良かったと思います。とくに半分に途切れている道パターンと紫生物が道の真ん中に出るコンボは、へたに避けるとジャンプ距離が足りず下に落ちやすいです。

アセットづくり

今回の3Dモデルづくりは、全部Blenderでやりました。まだ慣れてなかったのですが、このゲームではリギングやアニメーションが必要なくてモデリングだけだったので学習もかねてやってみました。モデルの形状も比較的シンプルなものばかりなので良い練習になりました。

f:id:mi-zmix:20210928002348p:plain

ぷちスタ用の作業では、スピード重視でMagicaVooxelと3Dcoatを使って作りましたが、ぷちコン用になおすときにBlenderとSubstancePainterで仕上げました。

未知の生物の表面は SubstancePainter で、トカゲの皮とかにしてみたのですが、「キモっ」ってなったのでやめておきました。やりすぎよくない。 なので、ベタ塗りのままにしました。ベタ塗りでもPBRのラフネスのおかげで、そこそこいい感じになってくれる気がします。

 

おわりに

エンドレスランナーは、ぷちコンならではという感じで気軽にできたのでよかったです。シンプルで作りやすいですし。

ぷちスタの課題には「スライディング」もあったのですが、操作がもう一個増えてしまうのが少しいやだったので実装は見送りました。

今回はぷちスタがあったおかげで企画段階で悩まなくてすんだので助かりました。今後もぷちコンが開催されるたびにぷちスタも開催されると、アイディアが出てこない時に助かると思います。