Unity経験ほぼゼロの状態から1年半でツインスティックシューター『NeverAwake』を完成。その開発方針から具体的な工夫まで解説【IDC2023】

2024.01.12
注目記事ゲームの舞台裏講演レポートUnity
この記事をシェア!
Twitter Facebook LINE B!
Twitter Facebook LINE B!

2023年12月17日(日)、インディーゲーム開発者向けカンファレンス『Indie Developers Conference 2023』が東京・新橋で開催されました。

本記事では、1年半という定められた開発期間の中で初めて本格的に触れるUnityとどう向き合って技術を習得し、ツインスティックシューター『NeverAwake』のリリースに至ったかについて語られた講演「1年半でNeverAwakeを完成させるための技術習得」についてレポートします。

TEXT / じく

EDIT / 藤縄 優佑

目次

講演に登壇したのは、『NeverAwake』を開発した株式会社ネオトロの佐渡 大志氏。同作の開発にあたっては、企画・ディレクション・グラフィックデザイン・プログラミングなど、そのほとんどを担当しています。

佐渡 大志氏

『NeverAwake』の開発方針

佐渡氏が開発した『NeverAwake』は、目を覚まさない少女「レム」がみる悪夢を舞台に、彼女の嫌いなものと戦うツインスティックシューターです。2024年1月現在、Steam/Nintendo Switch/PlayStation 4/PlayStation 5/Xbox Seriesで発売されています。

(画像は『NeverAwake』公式サイトより引用)

(画像は『NeverAwake』公式サイトより引用)

悪夢系アクションシューター『NeverAwake』STORY TRAILER

『NeverAwake』は予算の都合で開発期間が1年半と定められていました。開発チームはイラストレーション・BGM・SEの制作が各1名、それ以外はすべて佐渡氏が担当。

『NeverAwake』開発チーム

主な開発ツールはUnityBlenderで、開発スタート時点での佐渡氏のUnity経験はほぼゼロだったそうです。

やりたいことを取捨選択した結果、Unityでは開発環境の学習やC#の使用を優先する一方でシェーダーを捨て、Blnederではモデリングを捨てる代わりにリギングやモーションを自ら行いました。

本作の開発ではUnityの学習も兼ね、機能は純正に絞って自前で処理を書くようにしていましたが、2日以上悩むことがあればアセットも使いました。

学習は開発中だけでなく、休日や空き時間も書籍・Webサイト・動画などを見る習慣を付けて“Unity漬け”の生活を送っていました。

『NeverAwake』の開発環境は“チート”?

『NeverAwake』の開発環境は、佐渡氏にとってチートのようだったといい、その理由を4つ挙げました。

1点目は、同じシューティングゲーム(以下、STGと表記)作家でUnityを使用する友人がおり、困ったことがあればすぐに相談できたこと。

2点目は、iGi(※)の1期生に選ばれ、『NeverAwake』の作品のクオリティ向上やUnityに関する相談が可能だったこと。

※ iGi indie Game incubatorは、日本在住のインディーゲーム開発者向けの無償インキュベーションプログラム。開発・ビジネス・コネクション、そして作品を世界に届けるサポートを行っている

3点目は、パブリッシャーがコンシューマー版への移植に関するさまざまなサポートをしてくれたこと。

そして4点目に、自分自身の会社だからこそできることとして、1日あたりの労働時間としておよそ12時間を費やせたことを挙げました。

土日などの休みは確保していましたが、ある程度はプライベートを犠牲にして開発していたそうです。

講演では、ここから開発の過程を時系列順に紹介しています。

Unityでモックを制作(2020年11月~)

開発は、まずUnityでSTGを作れるかをたしかめるため、モックの制作からスタートしました。

当たり判定処理

Unityで当たり判定を実装する際は、ColliderRigidbodyを使うのが一般的です。しかし、STGでは敵弾が1,000発出ることも起こり得るため、処理速度を優先。C#を用いて自前で実装しました。

実装は昔ながらの円と回転矩形の判定を用いました。最適化の段階でこれらをすべてC# Job System(※1) & Burst(※2)化したところ、処理速度が10倍ほど速くなりました。

※1 アプリケーションで使用可能なすべてのCPUコアを使用して、コードを実行できるようなマルチスレッドコードを作成し、ゲームパフォーマンスを向上させる
※2 UnityのJob Systemに対応したコンパイラで、アプリケーションのパフォーマンスを高めるコードを作成できる

オブジェクトプーリング

敵キャラなどのオブジェクトを生成するたびにInstantiateしてしまうと負荷がかかるので、あらかじめ必要となるオブジェクトを作成して出す・消す・非表示にする処理を行いました。

ステージのオブジェクト予想必要数は、ステージエディタである程度自動で算出できるようにしていました。

当たり判定に必要なColliderもプールしたものを使用

コントローラー対応

Unityのコントローラー対応には、新しく導入されたInput System、エディターに組み込まれている旧バージョンのInput Managerの2種類があります。それぞれの動作を検証してみたところ、ボタンを押してから画面に反映されるまでInput Managerでは3フレーム、Input Systemでは6フレーム(2021年検証時点)でした。

自身もSTGプレイヤーである佐渡氏によれば、STGプレイヤーは3フレーム遅延なら許容、4フレーム遅延だとアウトと判断するだろうと考え、旧バージョンの入力システムを使用することにしました。

ただし、旧バージョンの入力システムは各種コントローラーへの対応が煩雑です。これはRewiredというアセットを使用して解決しました。

UpdateとFixedUpdate

Unityを使用するにあたり当初分かりにくかったのがUpdateFixedUpdateという仕組みだったと佐渡氏は振り返ります。これらは、どちらもフレームごとのタイミングでループ処理を行います。

Updateはモニターのリフレッシュレートの回数分だけ処理を実行しようとします。“実行しようとする”というのは、処理負荷がかかってしまうと処理落ちが発生し、命令の実行回数が均一でなくなるという意味です。

FixedUpdateは毎秒指定回数分、しっかり命令を実行します。ただし、処理負荷がかかった場合は画面がスローになりますオールドスタイルなSTGでは、大量の弾幕をFixedUpdateの処理落ちを活用してかわすゲームもあるとのこと。

『NeverAwake』は、1秒間に60回という内部処理は確保しつつハイリフレッシュレートに対応したかったので、当たり判定・座標系処理などの内部処理はFixedUpdateで60fps固定、アニメーション処理・UI・メニューなどの表示部分はUpdateで可変フレーム対応としました。

ここまでのモック制作で、佐渡氏はUnityでSTGを作れそうな手応えを感じられたと話します。

開発の「超」初期段階だとする動画

世界観に沿うグラフィックの制作(2020年12月~)

少女の悪夢が舞台である『NeverAwake』。悪夢感のある絵作り・悪夢的世界観の構築をローコストで作る方法を調査しました。

悪夢感のある2Dイラスト表現

基本は、手描きの2Dイメージにノーマルマップ(法線マップ)、ライティングをプラスさせ印象的な絵を作りました。

特定方向から光が当たるような描き方は、ライティングが変わったときに違和感が生じてしまいます。イラストレーターを含めて検討を重ねた結果、正面からライトが当たっている2DイラストにUnity側で陰影を付けるこの方法に決まりました。

視認性を考慮したレイヤー構造

印象的な絵作りも大切ですが、STGとして視認性を確保するのも大事な要素です。そこで、レイヤー構造は前面のノーマルマップを付けたオブジェクト・その間の仕切りとしてのフォグ・背面のオブジェクトの3つに分けています。

陰影処理は前面のオブジェクトのみ、背面は逆に濃淡を少なくすることで視認性を確保

悪夢っぽい違和感を演出する

『NeverAwake』の舞台は悪夢なので、佐渡氏はどこかに違和感のある映像にしなければと考えていました。そこで、例えば以下のワールド2の背景では、静止画では普通に見える道がキャラクターを動かすと歪んで見えるようにしています。こうした効果は、実際に3D上で歪ませたり傾かせたりして配置しました。

自由なカメラ移動ではなく自動スクロールするSTGなので、こういった騙し絵的な表現も積極的に取り入れて違和感のある雰囲気を作り出している

アニメーション

アニメーションはUnity純正のAnimatorとAnimationを使用し、ボーン入れ、リギング、メッシュアニメーションの工程を経て制作しました。

AnimatorとAnimationは処理速度が遅く負荷も高いといわれていましたが、最近ではBurst対応もされているらしく、いわれているほどの負荷は感じなかったそうです。

開発2か月目のこの辺りで、どんなクオリティの絵作りができそうかという算段が付いてきました。佐渡氏としては目を引く絵にできそうだと考え、この方針で進行することに決断しました。

開発2か月目の状態

最新型STGを目指して手触り感を向上させる(2021年1月~)

『NeverAwake』は、近年のインディーゲームの流行も積極的に取り入れたSTGにしたいと画策していました。ゲームに取り入れた要素を紹介します。

ヒットストップ

インパクトの瞬間などに画面を一時的に停止したりスローにしたりして、手応えの向上を狙うヒットストップ

テンポを阻害してミスに直結することもあるのでプレイヤーに嫌われることもある演出ですが、今回は最新型のSTGを作ろうと考えてヒットストップを積極的に取り入れました。

ヒットストップの基本パラメーターには、「静止するフレーム数」と「スローモーション時間」を設定しました。ヒットストップはフレームを静止させるものと思われがちですが、スローモーションも併用することで効果が上がると佐渡氏は考えました。

これに加えて、武器側と敵側でもそれぞれパラメーターを準備。例えば「武器によっては一定以上HPを持つ敵のときだけヒットストップする」「ショットガンのような武器は近距離で敵に着弾したときだけヒットストップする」「反射レーザーのような武器は一切ヒットストップしない」といった、武器と敵の掛け算でヒットストップの反応を変えています。

これにより、武器や敵が変わると手触りも変わる実装になっています。

射出位置と当たり判定

細かいこだわりとしては、自機の当たり判定と自弾の射出位置の整合を取りました。これがないと操作感が気持ち悪いだけでなく、当たり判定のズレによる事故の原因にもなります。

『NeverAwake』では操作キャラの首を当たり判定の中心にし、弾を射出する手が360度どの角度を向いていてもズレないように調整しています。

イージング

メニューやオブジェクトのイージング(動きの速度に緩急をつける)による演出は、快適な操作感を実現するために最小限にしました。

制作側としては、つい気持ち良くなっていろいろと動かしたくなりますが、プレイヤーのインプットにクイックに反応する操作感を最優先にしています。代わりに揺れものなどのオマケの動きで違和感をカバーするようにしました。

これらの調整や工夫を経て、ノータイムでコントローラーに反応する自機と敵を倒した時の手触りを兼ね備えた実装ができあがりました。

ほぼ完成時の映像

その他の機能実装(2021年1月~)

インゲーム以外の機能実装は必ずしも楽しいものではありませんが、今回はUnityを学ぶためということもあり粛々と実装することに。

マスターデータ

『NeverAwake』はそれほど規模の大きいゲームではありませんが、ステージ数は80、武器やアクセサリーは合わせて100以上。ストーリーや多言語対応もしており、そこそこのデータ量を備えています。

マスターデータの生成や管理方法はいろいろありますが、佐渡氏は効率化のためにGoogleスプレッドシート上に直接コードを書く手法を取りました。シートのセルにそのまま書かれたクラス、セパレーター、引数などを、テキストリーダーに直接コピー&ペーストすればC#コードになるという仕組みです。

この手法は細かい仕様変更や微調整に耐えやすく、規模の小さいプロジェクトに適している、と佐渡氏は語りました。

データセーブ

セーブデータは素直にJSONの文字列にして、それをSHA256(※1)で暗号化保存しています。

ファイル保存の処理はコンシューマー機ごとに異なるので何かしらラップ(※2)をしていたほうがいいとのこと。

※1 任意の長さの入力値から256ビットのハッシュ値を生成する関数
※2 既存のコード(関数、クラス、ライブラリなど)を包んで別の形で提供すること

データ保存では改ざんされる恐れもあるので、何かしらセキュアな方法を取るべきだと佐渡氏

ステージエディタ

ここで、続くステージ量産フェーズに備えて、ステージエディタの準備をしました。

『NeverAwake』では、基本のスクロール処理などはUnityのTimelineを使用しています。画面に各シンボルが入ることがオブジェクト出現のトリガーとなります。

ステージエディタは、敵キャラなどを出現させScriptableObjectにデータを保存する「録画モード」とそれらを再生させる「再生モード」に分けました。このようなモード切替は本来なくてもよいのですが、少しでも実行時の負荷を下げるためにこのような構造にしたそうです。

量産~仕上げ(~2022年6月)

ここまでの機能実装の工数はそれほど大きくなく、最もボリュームがあり期間も長いのがこの量産~仕上げのフェーズです。佐渡氏は、基本的に必要なのは“気合”としていて、いかに効率よく自分自身を飽きさせずに量産をこなしていくかが大事なのだそうです。

通常ステージとボスの量産

まず、通常ステージの開発です。『NeverAwake』は全80ステージ、ボスは全24体いてかなりのボリュームです。これだけステージ数があるとプレイヤーも退屈してしまうので、見た目やどんなプレイをプレイヤーにさせたいかという全ステージのコンセプトを80ステージ分全部書き出しました。

それらをプレイヤーの成長に合わせたレベルデザインを踏まえて「この順番で出したらプレイヤーも飽きないだろう」とシャッフルしていきました。このようにステージコンセプトを最初に決めておくと、ステージ開発そのものに悩む時間が減って効率が上がり、全体像をつかみやすくなります。

開発は1ステージにつき約1日、ボス戦は1体につき4日で完成させるという目標で進めました。

ボス戦は1日目が画像の切り分け、ボーン入れ、リギング、2日目でアニメーション、3~4日目で攻撃の実装というスケジュール感です。

ハードスケジュールではありますが、初期構築時は70%くらいの完成度で済ませておくのが良いと佐渡氏。詰めは時間がある時に後からすればよく、また、他パート進行時にさらに良いアイデアが出る可能性もあります。100%を目指すといつまで経っても終わらないので、完成クオリティの見極めを自分の中でしっかりと持つのが大事だそうです。

最適化

Unityを学び、それなりにしっかり組んでいるつもりでしたが、Nintendo Switchで動作させると15fpsくらいしか出ませんでした。STGでは30fpsでも手触りが悪く、60fpsを死守しなければならないと考えて最適化を試みました。

方法としては特別なことはせず、プロファイラとフレームデバッガで粛々と対応していきました。描画のドローコール(※)を抑えたり、CPUの処理負荷のボトルネックを特定して潰したり、マテリアルとスプライトアトラスの最適化をしたりしています。

※ グラフィックスAPIを使用して画面に描画を行う際に呼び出す命令。オブジェクトや要素をレンダリングする回数を意味する

また、先に述べたとおり、当たり判定や一部の計算処理をC# Job System & Burstに移行することで場合によっては10倍くらい早くなることもあり、CPU処理でボトルネックになっている部分が明らかに分かる部分があればこういった手法を検討するのも良いとのこと。

他にも、制御があまり必要ない連番のスプライトアニメは動作の軽いパーティクルシステムに移行するなどしました。

それでもNintendo Switchでは若干フレームレートが足りなかったので、一部の敵機をAnimationから連番のスプライトアニメに移行したり、ロースペック時のみライト数を減らしたりする調整を行いました。

スライド内右側の画面で、左はライトが4つ、右は2つになっている。見た目上では差をほとんど感じない

コンシューマー移植

コンシューマー移植に関しては、まず機種依存になるところをあらかじめラップして、機種ごとに処理を振り分けられる仕組みを持たせるのが大切と佐渡氏。

例えば、以下のような箇所が機種依存となると考えられます。

  • コントローラー周り
  • 決定・キャンセルボタン(Nintendo Switchでは逆になる。PS4では変更可能なため、両方対応が必要)
  • データ保存(ファイル入出力/同期非同期)
  • 実績・トロフィー
  • ボタン名称やアイコン(チュートリアル内の説明にも注意)

また、Unity開発の場合は、外部アセットの読み込みのためにAddressableを導入し、Nintendo Switchでの動作検証をするのがお勧めだと佐渡氏。Nintendo Switchで最適化を進めておけばプロジェクトのトータルの動作負荷も下がっていきます。

テストプレイ

STGで遊んだことのないような方を中心とした初心者層と、トップスコアラーのような上級者層、それぞれの層でテストプレイを実施しました。初心者層には作品が遊びやすいか、クリアまで到達できるかを、上級者層にはSTGとしての強度、やり込みに値するゲームになっているかをチェックしてもらいました。

目的に合わせてテストプレイ層を変えると、広い客層にリーチするゲームになりやすいです。

こういった1年半にわたる工程を経て、2022年6月に『NeverAwake』は完成しました。パブリッシャーの販売計画に準じ、9月の発売まで細かい調整やコンシューマー版の移植作業を行いました。

開発時に生まれた工夫

最後に、開発に関する工夫や実体験が披露されました。

イラストレーターさんが+αで描いたイラストは他のシーンで再利用し、なるべく素材を無駄遣いしないようにした

同じ素材でもエフェクトや見せ方を変えれば、使い回しをしてもプレイヤーはほとんど気にならない

すべての環境でUnityの同バージョンを使用した開発は困難になるので、SVNサーバを用いた1ソース運用を行った

誰かが損をするものでもなくWIN-WINの話題作りになるので、他作品とのコラボレーションは萎縮せずにやるべきとも話す

『NeverAwake』スペシャルコラボレーショントレーラー

本講演では、STGをUnityで開発する際に役立つ技術情報が多く語られました。それと同時に、限られた期間で開発するために佐渡氏が実施した数々の工夫が共有された点も大きな特徴で、聴講者に知見をもたらす価値ある内容でした。

『NeverAwake』 公式サイト「Indie Developers Conference」 Xアカウント
じく

ゲーム会社で16年間、マニュアル・コピー・シナリオとライター職を続けて現在フリーライターとして活動中。 ゲーム以外ではパチスロ・アニメ・麻雀などが好きで、パチスロでは他媒体でも記事を執筆しています。 SEO検定1級(全日本SEO協会)、日本語検定 準1級&2級(日本語検定委員会)、DTPエキスパート・マイスター(JAGAT)など。

関連記事

Unityの「Humanoid」を活用しつつ、揺れ骨など独自ジョイントを制御するには。QualiArtsによる「CEDEC2024」講演の補足記事が公開
2024.10.08
「Unity 6」で登場する「VFX Graph」新機能について、Unity Japanが解説動画を公開
2024.10.01
ゲームプログラミングにおけるデザインガイド、ユニティ・テクノロジーズ・ジャパンが日本語版の電子書籍を無料公開
2024.09.30
Unity公式によるアーティスト向け2Dゲーム開発ガイド、日本語版電子書籍が無料公開中
2024.09.25
「Unity 6」の全世界リリース日が10/17に決定。リアルタイムシネマティックデモ『Time Ghost』も初披露
2024.09.19
Unity Technologies、ゲーム領域の「Unity Runtime Fee」の導入撤回など料金体系の改定を発表。Unity Personalは適用範囲が拡大した一方、Pro/Enterpriseは値上げへ
2024.09.13

注目記事ランキング

2024.10.08 - 2024.10.15
VIEW MORE

連載・特集ピックアップ

イベントカレンダー

VIEW MORE

今日の用語

レベル(Level)
レベル
  1. ゲーム開発において、位置情報を持つオブジェクトが配置されている地形。
  2. RPGなどのゲームにおいて、キャラクターの成長度合いを示す数値。レベルアップなど。
VIEW MORE

Twitterで最新情報を
チェック!