RANDOM-MARATHON
【RM】3Dアクションゲーム「Ruins」
公開日:
2020/06/10
【RM】3Dアクションゲーム「Ruins」

はじめに

4/29~5/29の一か月間に部内で行われたチームでの共同開発競争「Random Marathon」において、3Dアクションパズルゲームを制作しました。

このゲームは、唐突に飛行機が廃墟に不時着したところから始まります。廃墟に住み着いている黒い影から逃げつつ廃墟内を探索し、パーツを集めて飛行機を修理し脱出を図るゲームです。また、廃墟内に落ちているアイテムを取ることでプレイヤーのできることが増えていき、様々な攻略の仕方があるゲームとなっています。ちなみに「Ruins」という名前は廃墟の英訳由来です。

メンバーは、IWANKIKMarcusやたぺんぎん の4人で制作しました!

IWANK

この作品で主にコーディングをIK氏と、またUIの仕上げを担当しました。

コーディングに関しては、主にプレイヤーの基本動作やスコア、UI関連を実装しました。
プレイヤーの基本動作というと、前後左右に動いたりジャンプしたりすることなんですが、これをアニメーションと連動させるのがまぁ難しい...。前後左右に動かすことについては、プレイヤーがある方向に速度を持っているときに、その方向にプレイヤーのrotationを向けて走るアニメーションを再生するだけの簡単な実装にしたんですが、ジャンプの 跳び上がる -> 空中 -> 着地 の一連の流れを一つのアニメーションだけで管理しようとして失敗しました。というのも、ジャンプをしている時間が一定だと、ジャンプ開始キーであるスペースキーを押したときに一連の流れをまとめたアニメーションを再生するだけで済むので楽なのですが、実際はジャンプ開始点と着地点が完全に同じ高さじゃないとジャンプ時間が一定になりません。例えば、高台からジャンプをすると、もちろんその高さ分空中にいる時間が長くなります。ここで何も調整せずにジャンプアニメーションを再生すると、一定秒数経つと着地モーションが再生されるため空中で着地動作をしてしまうことになります。これじゃ流石にダメ。当たり前です。そこでRayCastとアニメーションカーブ等を使って実装しようとしたのですがなんか上手くいかない。空中で着地動作をしたり、着地してから数秒後に思いだしたかのように着地動作をする等...。
こんな時は~~~~~~~???切るッ!アニメーションを分割するッ! 多分これが一番楽だと思います。あくまで私が直感的に実装できて楽しかったというだけですが。ということでアニメーションを分割しちゃいます。具体的には、まず 跳び上がる -> 空中 -> 着地 を分割し、3つのアニメーションとして管理します。そしてスペースキーを押したら跳び上がるアニメーションが再生され、続けて空中にいる間、つまり接地判定(今回はBoxCastをプレイヤーの下に発射して判定しています)がtrueになるまでの間は空中の足を上げているアニメーションを再生し続け、その後接地判定がtrueになれば、着地のアニメーションを再生するようスクリプト側で調整してやります。これでなんとか実装できたはずです。

問題なくアニメーションが再生されたのでヨシ!なんですが、坂などの斜めな地形では接地判定が上手くいかないことがあり、なかなか足を下げてくれません。接地判定は何度も改良した部分なのですが、まだもう少し改良の余地がありそうです。
ここで余談なのですが、UnityにはCharacterControllerというコンポーネントがあります。物理演算を利用しない簡単なプレイヤー制御でいいならこれを使えば容易に基本動作を実装することができ、接地判定もすでに用意されている(ただしあまり精度は良くないらしい?)のですが、今回のゲームはもともと物理演算を利用した3Dアクションパズルゲームを作ろうとしていたので、最初からその選択肢はありませんでした。紆余曲折の後パズル要素はほぼ消えましたが、物理演算があるおかげで自然な動きになったり、予想だにしない攻略法があるかもしれないのでCharacterControllerは使わなくて良かったと思います。

UIに関しては、今回特別なことはしていないのですが、私としては初めてポーズ画面を作りました。

タイトルに戻るボタン等々がありますが、少しごちゃっとしてしまいました。本当は操作説明をここに直書きするのではなく、ボタンを用意してやってクリックすると操作説明の画面へと移るというのをしたかったのですが、時間の都合上カットしちゃいました。他にも音量調節バーとかがあれば良かったですね。ただ即席でポーズ画面を作ってなんとか形にはなったので、個人的には一安心してます。

あとゲームのグラフィック処理について、かなり重くなってしまったのが少し心残りです。影を焼いたり、マップの設定をいじったり、テクスチャの解像度を下げたりしたのですが、アセットの3Dモデルは強かった...。メッシュをベイクする等して3Dモデルによる描画負荷を抑えたかったところです。ただこれのおかげで3Dモデリングとその処理についてかなり興味が湧いてきましたね。

そういえば、隠し要素として実装したアイテムがあるのですが、そのオブジェクトのタグがUsuiBookでした。これは一体...?

今回のプロジェクトではUnityで3Dゲームを作った経験がなく常時手探り状態でしたが、なんとか形となりプレイアブルなところまで持っていけたのは紛れもなくこのメンバーで意見を出し合ってそれぞれが動いてくれたおかげです。本当に感謝です。そしてお疲れさまでした。
また「Ruins」をプレイしてくださった方々、プレイしていただきありがとうございます。動きましたか?クリアできましたか?結構難易度的には高めになってしまいました。多分初見だと難しいです。ぜひ何度も挑戦してみてください!

IK

今回の制作ではコーディングとネジの配置等のマップの調整を担当しました。

コーデイングについては,私が実装したのはカメラとブレイク機能とホバー機能です。どのように実装したのかや苦労した点について書いていきます。  カメラはかなり苦戦しました。最終的には右クリックをした状態でマウスを動かすとその方向に回転し続けるように実装しました。最初はFPSみたいな感じのを作ろうとしたのですが,コレジャナイ感が出てボツ。次はプレーヤーを中心に球形座標をとってその上を動かすという方法で実装したのですが,カメラが思うように動いてくれない。なぜかといいますと,下の画像のような移動になってしまっていたわけです(この絵でわかるかな……?)。

というわけでこれもボツ。正直上手いことやれば球形座標をつかってできると思うのですが数弱の私には無理でした……。で,最終的には「プレイヤーキャラ(以下、ロボットと称する)の子オブジェクトにカメラの回転軸の役割をもつ空のオブジェクトをつける」というものになりました。オブジェクトの親子関係についての説明は省きますが,ロボット>垂直回転軸>水平回転軸>カメラの順で親子関係になっています。実際には水平回転軸とカメラの間にはカメラのズームに関するオブジェクトが入っていますがズームに関しては上手くいかなかったので実装していません。3Dゲームはマジで数学が大事になるんだなあと実感しました。あと,カメラの移動方向と移動量に関しては「画面上で,マウスを右クリックした位置を原点とした,現在のマウスの相対位置からカメラの移動方向・移動速度に反映する」という感じになっています。回転の移動量は制限をつけて速くなりすぎないように調整しました。制限といえばカメラの垂直方向の回転角度にも制限がつけてありますが,ズームの制限がうまくいかなかったのがズーム機能がボツになった理由です。

次は追加機能関連ですね。ブレイク機能を取得すると,Eキーで物体を破壊できるかどうか判定するレーザーを出せるのですが、これの実装が一番苦労しました。最初は,見えないオブジェクトをロボットの胸のあたりにつけておいてボタンを押している時だけ見えるようにすることでそれっぽく見せようと考えたのですが,やってみるとcolliderの扱いが面倒+レーザーっぽく見えない+影ができるの問題が発生しボツになりました。次にRayCastを使ってボタンを押している時だけRay(当たったものの情報を取得できる見えない光線)を発射し,破壊可能判定を行おうとしたのですが影のできないレーザーっぽい見た目のオブジェクトが全く作れずかなり苦戦していました。それで何とかLine Rendererなるものを見つけ,ようやくレーザーっぽい見た目のものが実装できました。「Unity レーザー」とかで検索をかけてもRay関連のことしか出てこないので地味に大変でした。Line Rendererを使う上で必要なテクスチャを私がCLIP STUDIO(お絵かきソフト)で書きました。ホバー機能については,プレイしてくれた人ならわかるかもしれませんが,バグが存在します。ホバー中に着地できないぐらいの角度の斜面とぶつかったりすると変な挙動になります。処理としてはホバー中だけロボットのUnity上の3D座標y成分を固定しているのですが,固定している状態でそれを変化させる方向の力を加えると,挙動が変になるのだと思います。今回は開発期間的にその部分を直している余裕がなくそのまま放置されています。ホバー状態が終われは挙動も元に戻るので,ゲーム性を破壊するようなことはないハズです、多分。

そしてマップについてですが,やたぺんぎん君の作ってくれたマップが非常に完成度が高かったおかげでネジ(クリアするのに一定数集める必要があるアイテム)を配置する場所は決めやすかったです。追加機能を取らなくても初期能力のモノを持つ能力とジャンプだけで最低限クリアできるようにはしたつもりです。あとやったことといえばゲームのコンセプト決めたりするのにアイデアまとめたりしたぐらいですかね。制作の最後のほうは私が所属している他団体の活動と被ってあまり何もできてないの申し訳なかったです。

今回の1ヶ月という期間で制作を行いましたが,スケジュール管理というか進捗管理をする人は必要だなと思いました。もしもっと大人数で制作する機会があれば(個人的にはしてみたい)そういうマネージャー的な人を決めたほうがいいですね。あと3Dアクションは作るのが難しいということがはっきりと実感できました。また,反省点としてはプログラミングの勉強をあまりしていなかったのでコーディングに時間がかかり,バランス調整等他の作業の時間が相対的に減ってしまったことです。スクリプトの数も無駄に多くなり,正直人に見せられたもんじゃないです。プログラミングの勉強しなきゃ(使命感)。

最後に,今回一緒に制作してくれたチームのみんなと遊んでくださった方々に感謝を。初めての共同制作で大変なことも多かったけどとても楽しかったです。また一緒に制作することがあればよろしく。

Marcus

私が担当したのはアセット集めとタイトル画面です。
みんながなんだかいろいろすごく頑張ってる中自分のやったことがすごく少なくて申し訳ないです。みんなすごいです。
Terrainで地形を作ろうとしたこともあったのですがなんだかよくわからないことになってよくわからないまますごい意味不明な地形ができているところにやたぺんぎんさんが作ってくれました。すごいです
私の作った部分の話にしましょうか。
長文で特に内容はないので飛ばしていいです。

ここから


タイトル画面を作るにあたって、まず画用紙にタイトル画面の案を書きました。個人的に気にしたことは主人公の目的を暗示するということでした。今回であれば走るモーションを与えました。これは今回の主人公の行動がものを探し集める行為だったからです。私はタイトル画面はゲームの特徴を示すものであればいいなと考えています。ロックマンエグゼなら主人公の名前であるタイトルを大きく書き、背景に舞台であるサイバー空間のイメージを流す、といった形で、Bloodborneなら霧をこもらせることで不穏な空気を演出した、本作の舞台である町にひとり向かう主人公の背中、といったタイトル画面ですね。このタイトル画面の主人公はただ棒立ちをしているよう、実際棒立ちですが、でありながら、町に体を向け、プレイヤーには背中を見せることで本作の主人公の目的である「町の奥へ向かう」ことを演出しているといえるでしょう。また、主人公の右手に近接武器を左手に銃器をという少々特異なスタイルを先出しすることにも成功しています。このように、タイトル画面は見せたいところを端的に見せることがキモなのだな、と感じました。ですので、今回、タイトル画面で一押しにしようと思ったのは、主人公が走ってものを集める、このゲームのシステムそのものであろう、ということでした。ですので、左上に大きく今回集める物体をデン!と置き、それに向かって走る形で主人公を配置しました。このとき主人公の顔がこちら側に見えるように角度を調節したので厳密にはボルトの方向は向いてませんがね!そしてもう一つの目的である飛行機をみえるところに配置し、これでとりあえずは主人公の目的の設定としました。あとはさみしいので舞台の設定でもと思い、主人公の後方に家を設置して、いったんIWANKに相談、まださみしかったうえに舞台には自然があるということで木を設置しました。これがタイトル画面の成り立ちです。作っててなかなか楽しかったです。ちなみに何の意味もない情報ですがあのタイトル画面にある物品はそれぞれ拡大されていて、大体実際のゲーム画面の3Dモデルの倍くらい(ボルトはたしかもうちょっとでかい)になっています。これはカメラの位置を調節するときに、カメラの位置を細かく動かすよりも、今のカメラをもうタイトル画面だ!と考えてカメラの画面を見ながらキャラの大きさと位置を調節したからです。動かすキャラとステージじゃねえからいいんだよ(適当)でも個人的には少なくともタイトル画面に関してはこっちのほうが絶対に作りやすいと思うお


ここまで

さて、最後に
このゲームを遊んでくださったみなさま、本当にありがとうございます。楽しんでいただけましたならしあわせにございます。
今回一緒につくったメンバーの皆さん、おんぶだっこで本当に申し訳なかったです。皆さんすごかったです。ありがとうございました!またいつの日にか

やたぺんぎん

マップの作成、ゲーム説明シーンの作成、アセット集めを担当しました。

ここでは一番苦労したマップ作成について書こうと思います。マップ作成はunityのTerrain機能とアセットを用いて行いました。 まず背景づくりです。マップは背景に一つでも不自然な点があったら台無しになってしまうので気を付けないといけません。しかし、普段触っているUE4では背景用の素材があったので延々と続くフィールドが表現できたのですがUnityで探したところ素材が見つかりませんでした。(めちゃくちゃ焦りました)そこでTerrain機能でめちゃくちゃ大きな山を作り、プレイ範囲を囲むことで盆地っぽくしてとりあえずプレイヤーの見える範囲は違和感ないように仕上げました。
↓の画像はマップ作成初期の時です

また、Ruinsというテーマなので大体の地形を作った後のアセットの配置バランスに苦労しました。廃墟というかポストアポカリプス感が出したかったので某鬱ゲーシリーズの最新作のマップを参考にして、自然4:1建物といった比を意識して作りました。また、これはあまり機能してなかったので裏話ですが、キーボード操作に慣れてない方のことを考慮してスタート位置周辺は簡単な凹凸を配置し操作に慣れてもらう感じにして、離れるにつれてギミックを難しくするといったレベルデザインを考えて作成したつもりでした。 ↓の画像は作成がほぼ完了した時の画像です。

マップ作りは苦労しましたが、これまでの自分のゲームの経験が生かせたので楽しくもありました。例えばマップ右上の追加機能入手後でしか行けない(はずだったのですが傾斜ミスってて機能なしでもあるルートから普通に行ける)高台は某国民的RPGの8作目に出てくる、空を飛べるようになった後に行けるようになる高台をイメージして作っています。

今回のRMは共同、またunityでの開発ということで初めて経験することが多く、とても不安だったのですが、良い経験になりました。また、(コード書けるようにならないと!)と実感しました。プログラミングのお勉強頑張りたいと思います。最後に、自分のような新参者をやさしく迎えてくださった制作チームの先輩方とこのような機会を与えてくれたランダムに感謝します。ありがとうございました。また、これを見ている皆さんがRuinsを楽しんでいただけたのなら嬉しいです。

おわりに

今回私たちは3Dアクションゲームを作りましたが、4人ともそれまで1か月にわたる共同開発の経験はおろか、Unityで3Dゲームを作った経験もありませんでした。
こんな4人が初めてやることに果敢に挑戦して生まれたのがこの「Ruins」です。
初めてのことだらけで大変でしたが、それぞれが新しいことに挑戦するいい機会だったと思います。

そんなRuinsを遊んでくださった皆さん、本当にありがとうございます。(マシンスペック等により遊べなかった方々には深くお詫びいたします。)
今のところ制作陣のスコア111500点を上回る報告を受けていないので、もし超えられた人がいたらご一報ください!

RVWは6月いっぱい公開しています。部員による渾身の作品が遊べるのでぜひ遊んでいってください!\ゆっくりしていってね!!!/

https://virtual.ch-random.net/

最後までご覧いただきありがとうございます。明日以降も他のチームが記事を投稿するのでそちらの方もぜひご覧ください!

loading...