2021年の夏に行われた第16回ぷちコンと,それに並行して行われたぷちスタの振り返り.
第16回のぷちコンテーマは「みち」であった.
ぷちスタは1週間でゲームを形にしようという企画.お題は「みち」のテーマに合わせてエンドレスランナーを作るというもの.この前にあったアンリアルクエストに引き続き課題をクリアすることでゲームが出来上がっていく.
そしてこのぷちすたの作品をマテリアルなどの微調整やギミックの追加などを施して,ぷちコン提出作品「TailWind」としました.スピード感を演出したかったので追い風という意味です.
UEイベントは今回が2回目でぷちコンは初参加でした.
なお,このイベントでエンドレスランナーを作るにあたって公式の以下の動画は非常に参考になった.
ぷちスタ編
自動的に前に走る
自動的に前方方向に進ませるのはそこまで難しくなく,もともとのキャラクターに入っているノードをつなぎ変えればよい.TickでAddMovementInputを利用し,前方のdirectionやdeltatimeと走行速度の積によるscale valueが正しければ,Tickにより毎フレーム自動で前に進んでくれる.もちろんアニメーションも機能する.
左右キー(A/D)で横に移動できる(前に行く速度は変わらずに)
前方に進んだ状態で横移動を入力すると,そのままの状態では前方に向いていたベクトルを真横に傾ける処理となるため,前に進む速さは減少してしまう.
そこで横への入力を変数として保持し,三平方の定理によってベクトルの大きさを横方向の成分の分増大させることで前方方向への速さを変えずに横に移動できるようにしてある.
AxisValueには-1から1の値が入るので,前方を0度とすると‐45度から45度までカバーできており,キャラクターの速度としては45度かマイナス45度の時最大となり,0度の時最小値を取る.
下段は正面方向が変化するときに必要な処理.ForwardAngleには正面方向がworldに対し0度,90度,180度,270度のいずれか回転していることを表し,場合によって力を加えるworldDirectionを変更させている.
走っている少し先にコースが自動的に生成される(通り過ぎたコースは消える)
この部分は主に上記の参考動画を参考に作成した部分.
エンドレスランナーを作る核の部分でもある.
この処理を行うスクリプトに関して,GameModeやレベルブループリントに配置するなどいくつかのやり方が考えられるが,この時の私はPlayerキャラクターのブループリントに配置する手法を取った.
プレイヤがスポーンされると15マス分の床が生成される.画像では何やら怪しいSwitchノードが見えているが,これは確率によって生成する床Actorを変更するため.
床アクタには次の床をどの位置につなぐかを示すAttachPoint(ここは参考動画を参照)があり,この位置をキャラクターの変数に返すことで連続して床を生成することができる.
また通り過ぎたマスが消える処理については床アクタの上のエリアをBoxCollisionでおおい,EndOverlap を使うことでこのマスから出たことを判定する.
エリアから出ると15マス先に新たなマスが生成され,その2秒後にこのマスは消えるという仕組みになっている.
障害物の追加
今回は障害物として,炎のバーを設置した.バーの位置は高めと低めの2種類.
前者はジャンプしていると接触し,後者は逆にジャンプしてよけなければならない.
障害物が配置される床は上記の床生成のスクリプトによって一定確率で出現する.
炎にはCascadeのものを利用し,3つのParticleComponentによって通路を封鎖した.
炎のエリアに当たり判定を追加し,触れるとダメージを与え炎を消化するように設定した.
障害物にあたった時の,ダメージ or ゲームオーバーの追加
障害物に接触するとエフェクトと効果音を発生しつつダメージを受ける.
設定したヒットポイントの回数分ダメージを受けることができ,規定量を上回るとゲームオーバーとなる.isContinueをFalseとすることでレベルブループリントに伝わり,リザルト画面への表示に移行する.グレイマンの場合はラグドール化を行うが,今回は後ろの項目でキャラクターメッシュを入れ替えたことによりそのままではうまくラグドール化をすることができなかった.そのため代わりに点灯アニメーションを作成しこれを再生することにしている.
アイテム(コイン)の追加
コインに触れるとプレイヤのスコアが加算される仕組み.触れるとコインは消える.
ついでにコインは時間経過により徐々に回転する.
普段ならコインの当たり判定にはBoxColliderを使いそうだけども,なぜかこの時はActorOverlapを使っている.とはいえコイン程度なら実装上の差異はそこまでなさそう.
コイン自体はマップ生成の際にランダムで配置される.
のちにコイン以外も生成できるようになっているが,普通のコインは3分の1の確率で生成される.
Constructionscriptによって確率的にコインが生成される.
生成場所はSpawnListにTransformの座標候補を指定しておき,ランダムでその中から座標が一つ選択される.選ばれたその座標にAddActorChildComponentによってコインが配置されるようになっている.
UI(コインの取得数)の追加
UIはUMGで作成.表示するのは経過時間,コインの取得数をもとに計算されるスコア,
のちの特殊アイテムにより加算されるSpeedとJump,そして残機数の項目.
UIの生成はコースのレベルブループリントのBeginPlayで行う.
値の更新は同じくレベルのTickで行う.isContinueはプレイヤの生存を管理している.
プレイヤが生存している間はTickでUIで表示したい各値を取得し更新する.
経過時間はレベル変数.それ以外はキャラクターによって管理している.
経過時間についてはDeltatimeを都度加算することによって保持している.
アセットを入れよう
この課題はアセットをインポートしてゲームで使用しようというもの.
この前に取り組んだアンリアルクエストの時はグレイマンを操作キャラクターにしていた.
今回はキャラクターを変えてみようということでVroidで作ったキャラクターをVRM4Uでインポートし,使用することにした.
アニメーションも適切にリターゲティングすればグレイマンのものをそのまま用いることができる.
設定の問題かLitにしているためか若干絵的に浮いているような気もするが,自分のキャラクターが動いているのを見るのはグレイマンのアクションを見るのとはまた違った感動がある気がする.
効果音・BGMの追加
BGMや効果音は下記のサイトのものを主に利用した.
まずBGMについてはレベルブループリントのBeginPlayに配置.
この方法だとレベルを切り替えない限りBGMは止まらないが,今回のゲームではBGMが変化することはないので問題はない.
効果音はダメージを受けた時やコインを拾った時などにPlay Sound At Locationによって再生させた.
スタート画面の追加
UMGを使ってタイトルUIを作成する.
このころはアンカーの打ち方があまりわかっていなかったのでたまにレイアウトが崩れることもあった.画像は全面アンカー,ボタンやタイトルの文字は右側にアンカーしておくのが無難なのかなと.
タイトル画面の画像自体は,一段落ついた完成品の録画データからキャプチャしたものを利用した.
スタートボタンは押すとレベルを読み込む.ゲームプレイ時はマウスカーソルは不要なのでこの時点でカーソルを非表示にしておく.
呼び出す方のレベルにはレベルブループリントでUIを呼び出すためのスクリプトを作成.
この時UIはマウスで操作することになるため,PlayerControllerのShowMouseCursorを有効化しておく.さらにPawnはこのままでは自動でエンドレスランナーが始まってしまい,UIの後ろで動作してしまうので,Movementを無効化することで,対処している.
最初に15マスのマップが生成されてしまうのはこれでは防げないが,ギリギリタイトル画面としての機能を保つことができている.
リザルトの追加(結果の表示)→ボタンを押したらスタート画面に戻る
プレイヤキャラクタはLifeが0になるとisContinueがFalseになる.
UI周りはレベルブループリントで管理している.
Tickで毎回継続判定がかかっており,これがFalseになったのを確認しリザルト画面の表示に移る.
RemoveFromParentはもともとコイン表示などに使用していたUIを取り除く.その代わりにリザルト表示用のUIを生成する.リザルト画面ではマウス操作が必要なのでShowMouseCursorをTrueに.
Castのノードは画像では外れてしまっているがGetPlayerPawnに繋がっている.
キャラクターで管理しているスコアと,レベルブループリントで管理している経過時間をUIに渡す.
タイトルボタンはタイトル画面のボタンと同じ仕組みで,今度はタイトル画面のレベルを指定したレベル遷移によってタイトルに戻れる.
ぷちスタ提出作品「Tail Wind」
実際には次の追加実装も一部含まれていたが,ひとまず提出作品は以下のもの
ゲームとしては正直独創性がそこまでない単純なエンドレスランナーという感じである.
しかし習作としては自動生成のスクリプトなど新しい学びもあったので良かったのではないだろうか.
コメント