Unity を検索

生態系を作るシステム:創発的ゲームデザイン

2021年12月7日 カテゴリ: テクノロジー | 10 分 で読めます
Hero
Hero
取り上げているトピック
シェア

簡単なスクリプトを使えば、ゲームデザイナーは自分のゲームの中に面白くて予想外のゲームプレイをもたらすシステムを作ることができます。ゲームデザイナーの Christo Nobbs は、Unity のいくつかの主要な機能を利用して、創発的ゲームプレイをデザインするためのアプローチを説明してくれました。 

個人のクリエイターやゲームスタジオとの長年の対話から、ゲームデザイナーが Unity でゲームプレイやデザインの仕組みを作ると、チームの他のメンバーにゲームのビジョンをより明確かつ詳細に示すことができることがわかっています。

私たちは Unity でのゲームプレイのプロトタイプ作成、制作、テストの方法を学びたいゲームデザイナーのための e ブックThe Unity Game Designer Playbook」を新たに制作しました。新米ゲームデザイナーでもベテランゲームデザイナーでも、自分のプロフィールに Unity のスキルを加えたいと思っている方は、このガイドをぜひ参考にしてください。

システムゲームデザインと Unity(C#)を専門とするシニアテクニカルゲームデザイナーの Christo Nobbs もこの e ブックの執筆に関わりました。このブログ記事では、ゲームデザイナー向けのシリーズの第 1 弾として、Christo が e ブックで紹介したシステム設計のためのヒントや例について、より掘り下げて解説を行います。

Test project
火炎伝播システムとその結果として起こりうるカオスを説明するためのテストプロジェクトの画像。

ゲームデザインにおいて有用なシステムとは、明確な機能を持ち、データを保持し、モジュール化されていなければなりません。このようにして、別のシステムと相互作用できるだけでなく、他のゲームオブジェクト上の自分自身とも様々な方法で相互作用することができます。ゲームシステムの全体を考える際には、完全なアーキテクチャとしてではなく、ゲーム内で再帰的に実行される機能の一部としてイメージすることも有効です。

このようなシステムを組み合わせることで、プレイヤーの行動に反応し(隠されたハードコードされた値ではなく)デザイナーがパラメーターを操作しやすいように設けられた「デザインレバー」を使ってバランスを取る、ユニークな生態系を作り出すことができます。これらのレバーは、ゲーム内のキャラクターやシステムのデータを操作するために設置されており、結果的にゲームプレイ全体を構成しています。  

ほとんどのゲームには、ゲームプレイを通じて値を調整する単一の仕組みであったり、システムのネットワークであったりはしますが、少なくとも 1 つのシステムが存在します。『Age of Empires のような戦略ゲームでは、プレイヤーは資源をどのように活用し操作するかを学び、敵を倒して前進する必要がありますが、ゲームプレイを支配するのは複雑な生態系です。

プレイヤーにどのようにゲームを進めてもらうかは、最終的にはゲームデザイナー自身が決めることになります。ゲームプレイは、誘導された直線的な道筋に沿って設定されるべきなのか、それとも、有機的で創発的な結果を許す 1 つまたは複数のシステムの組み合わせによって駆動されるべきなのか。

モジュール式のシステムが面白いゲーム性を生む

小さなシステムを設計する際には、モジュール性や、自分自身や他のシステムとのインターフェース機能を優先すべきです。なぜなら、これらの機能は興味深いゲームプレイのループを引き起こすからです。1 つのシステムが別のオブジェクトを介して自分自身に衝突したり、2 つの単純なシステムが並立して共に動くことで、起こりうる反応の連鎖を考えたいのです。常にプレイヤーにとって機能が明確にわかるようにシステムを作るようにしましょう。そうすれば、プレイヤーはどのシステムがどのように機能しているのかを学び、有利な状況を作り出すチャンスを得られるようになります。

Oxygen Not Included
Klei の『Oxygen Not Included』

連鎖反応の例としては、『Oxygen Not Included』に取り入れられたものがあります。メインループの目的は、いくつかのシステムのバランスを取り、生物が共生するユートピアの状態を達成して繁栄を続けることです。また、Larian Studios の『Divinity Original Sin 2 には爆発して攻撃してくるモブがいますが、プレイヤーがこのモブを濡らしてしまうと爆発しなくなるため、戦いが楽になります。また、プレイヤーは地面に火をつけて、モブが走ってきたときに身を守ることができます。 

モジュール式のシステムは、あるシステムのパーツを使って別の異なるシステムを作ることができるため、ゲームにさらなる価値をもたらします。Christo がほとんどすべてのことに使っている Unity の機能の 1 つが、アニメーションカーブです。Christo いわく、「ゲーム中のオブジェクトのデータ処理はほとんどいつも同じやり方でやっています。単一の値でバランスを取るよりも制御しやすいです。また、仕組みの中にイージングを入れたり、システムの限界を超えてディテールを微調整することもできます」。

また、モジュール化されたデザインは、プログラマーに説明するときの正確性を可能な限り高めることができ、ゲームプレイのシステムを編集・デバッグしたり、ゲーム中にさまざまな構成で再利用したりする際に、効率的に作業を進めることができます。 

デザインレバー

デザインレバーは、値を調整して結果を操作するのに役立ちます。たとえば、ゲームプレイの難易度を上げたり下げたりすることで、やりがいがあり、狙い通りの複雑さを実現することができます。デザインレバーを使えば、意図した結果が得られるまで、何度も試して調整することができます。

デザインレバーは、ゲーム開発のコンセプトやプロトタイプの段階から、ポストプロダクションの磨き上げに至るまで使用することができます。Christo は、アイデアをフローダイアグラムに落とし込む際に、デザインレバーを加えると言います。プロジェクトの初期段階で、システムに必要なスイッチやレバーを考えておくと、後からコードのリファクタリングに頼らずに、微調整してゲームの可能性を探ることができます。

次の画像は、スタート時に敵がいる状態で、プレイヤーが武器の準備を整えて入ってくるというシンプルなゲームプレイを表すグラフです。基本的には敵を倒さなければなりませんが、デザインのレバーを操作することで、ゲームプレイを変化させ、焦点を移すことができます。ある設定では、制限時間内に多くの敵を素早く倒すハイスコアがゲームプレイの中心となり、別の設定では、制限時間内に一定量の敵を倒し、プレイヤーが奪われる前に落とした戦利品を拾う時間を確保することに重点が置かれます。

Gameplay design
シンプルなゲームプレイのデザイン

このシステムを使って、優れたドロップとそれぞれ異なる特性を持つ複数の種類の武器が存在する、完全な弾幕を作ることもできます。再生成にタイムアウトを設けるなど、デザイン上の工夫を加えることで、さらにシステムを拡張することができます。

『Escape from Tarkov』の武器作成システム

Escape from Tarkov』(Battlestate Games)は、Unity によるシステマティックなゲームデザインのもう 1 つの良い例を示しています。このゲームには、下の画像のように、独自のデータを持つ武器を作成するクラフトシステムがあります。このデータセットは、プレイヤーのステータスと同様に、銃の特性や銃によるゲームプレイ全体に影響を与えます。プレイヤーのステータスが健康なら武器をスムーズに扱えますが、手足の骨折や病気のステータスを負っているとだんだん銃を扱いづらくなっていきます。

Weapon from Escape from Tarkov
『Escape from Tarkov』の武器作成システム

武器システムとプレイヤーの健康システムとの兼ね合いがあることで、プレイヤーは自分のキャラクターの命だけでなく、より性能の高い武器も大切にするようになります。ダストカバーもストックもない不安定な AK を使って、ミスショットを連発したいと思うプレイヤーはいないでしょう。もしそのような状況に陥っているなら、それは使っている武器が現状では悪い選択肢であることを示す明確な兆候と言えます。 

また、装甲と同じように、異なる特性を持つ弾薬の種類も豊富にあります。相手の弾薬や装甲の種類によって、体のどこを撃てば最もダメージを与えられるかが決まり、そこにメタなゲームプレイが生まれます。これらのシステムは、それぞれに視覚的な手がかりがあり、デザイナーが求めていたゲームプレイの「本質」を生み出すようにバランスがとられています。

Escape from Tarkov
『Escape from Tarkov』のシステムは、リアルさを追求している。

デザインレバーとしての ScriptableObject

Unity でデザインレバーを設定する 1 つの方法として、ScriptableObject があります。これらは、アセットとして保存され、シーン内の他のオブジェクトに依存することなく、スクリプトから参照されるデータのコンテナとして使用できます。  

異なる値を持つ複数の ScriptableObject アセットを作成し、それらを共有したり交換したりすることで、プリセットのようにゲームプレイのセクション全体を変更することができます。再生モードで変更した内容は ScriptableObject で保存されるので、一旦終了してメモを見返して変更を実装する必要がありません。 

例えば、キャラクターのプロトタイプを作成する際に、ScriptableObject のアセットを別の値を持つアセットに置き換えることで、キャラクターの雰囲気を変えることができます。これは、バフやデバフのプロトタイプを作成したり、キャラクター選択とプロファイルを結びつけるためのゲートウェイとして使えるでしょう。

たとえば、シューティングゲームを作っていて、反動、発射速度、精度、射撃モード、オーディオ設定、ビジュアルエフェクト設定などのアクションに任意の値を設定した銃システムを実装したとします。新しい銃のプロファイルをいくつも作成し、再生モードで設定を調整して、それを保存することが一度にできます。また、これらのプリセットされた ScriptableObject をチームメンバーとの間でやりとりして、フィードバックを得ることもできます。これは、ゲームプレイに適した感触を見つけようとするときに便利です。 

デザインレバーは、公開のプロパティとしてコード内の単一の変数を置き換えることができ、Unity の RangeAttribute を使用して範囲を制限することができます。これにより、スクリプト内の浮動小数点数または整数を特定の範囲に制限しながら、インスペクターでスライダーとして表示することができます。再生モードに限らず、その場でレバーを操作することが意図されているので、編集モードで実行している場合や、ツールをテストしている場合にも適用できます。

Panels
1)範囲、ツールチップ、およびヘッダーの属性。インスペクターはデザイン上の要求に合わせてカスタマイズできる。2)Odin(アセットストアで入手可能)で作成したカスタムインスペクター。3)ScriptableObject に保存されたデータで、さまざまなデータセットやプロファイル(この場合はさまざまな特殊攻撃)を作成できる。

サバイバルゲームなどでは、プレイヤーはさまざまな選択肢の中から、論理的で合理的な結果を期待して、それぞれの課題に対する解決策を考えていくことになります。課題も解決策も、ある程度は創発の結果として得られるようなシステムを設計するにはどうしたらいいでしょうか。 

たとえば、Klei studio のゲーム『Don't Starve』のように、プレイヤーがあるエリアに留まらないと生きていけない場合を例に見てみましょう。プレイヤーは火のそばにいることで、敵の攻撃を防ぐことができます。また、火は食べ物を調理したり、プレイヤーが暖を取るためにも使えます。しかし、プレイヤーや食べ物、燃えやすいものを火に近づけすぎると、それらは燃えてしまいます。 

上記のような連鎖反応を起こすためには、どのようなシステムが必要なのでしょうか。火の周りに領域を作って火のそばに立つプレイヤーに時間経過で熱を与える、システムとして直線的な火の伝播を作るといった仕組みが考えられます。しかし、もっとシステムを重視したデザイナーのレンズでアプローチしてはどうでしょうか。個別の火炎伝播システムが互いに衝突したり、ゲーム世界に存在する他のシステムと衝突したりして連鎖的に発生する状況で、プレイヤーに反応を促したいのです。

Capsule Colliders
カプセルコライダーは、火炎伝播システムコンポーネントが装着されたゲームオブジェクト同士で熱を伝えあい、連鎖反応を起こすことができる領域を示している。ゲームオブジェクトが燃えていると、その部分が赤くなり、熱が加えられていることを示す。熱を受けたゲームオブジェクトは、熱を持っていることを示す黄色に変わり、その後発火して赤に変わる。

池の周りの決められた範囲の地形に、時間をかけて木が生えてくるというシステムが考えられます。これらの木は芽を出し、空間の限界に達するまで成長していきます。成木になった木は伐採して木材にすることができますが、もちろんこの木材も燃えるものです。  

プレイヤーはこの木材を使って、おしゃれな木製の椅子などのアイテムを作ったり、池の横で木材を使って小さなキャンプファイヤーを作り、泳いだ後に暖かく乾いた状態で過ごすことができます。しかし、それならば、プレイヤーに焚き火をする能力を与えたらどうなるでしょうか。

木についている可燃性のシステムは複雑ではありませんが、何かが燃えていると一定の半径内にわたって熱が放射され、その熱の値が近くの木製のアイテムや木の制限値を超えていると、これらも燃えてしまいます(単純な伝搬)。このように、プレイヤーはキャンプファイヤーに火をつけることで、素敵な木製の椅子にも火をつけてしまったのです。プレイヤーは、椅子をつかんで水に投げ入れて火を消さなければなりませんが、そうしているうちに、焚き火が近くの木に火をつけてしまい、森林火災が発生してしまいます。 

この例のような小さく、なんてことのないシステムであっても、プレイヤーに「台本のない」楽しい体験をさせることができます。また、現実にぎっちりと合わせたデザインではなく、プレイヤーに望む結果に焦点を合わせることが重要です。現実に合わせすぎると、予想外の結果を生み出す力が弱くなります。 

この例では、Unity で、火をつけたいものに配置した ScriptableObject にデザインレバーを仕込んでおくことで、創発的な可能性を生み出すことができます。まず、ゲームの世界の木を見てみましょう。水辺にある枯れた木がすでに燃えています。その木は水のほうに傾いています。そして、プレイヤーは暖を取りたいと思っています。

この例では、木にざまざまな値を持つ ScriptableObject が置かれています。

Panel
Code

これらの値をもう少し詳しく見てみましょう。

  • Default temperature(デフォルトの温度):グローバルな状態から何も継承しない場合のプレースホルダー値です。このグローバル値が高かったり低かったりすると、システム全体の感触に影響を与えます。すべての木が火の伝播システムを使用していると仮定すると、温度が高いと森林火災が発生する可能性があります。
  • Current temperature(現在の温度):アイテムの現在の温度で、加熱または冷却されることで変化します。この値で燃えているかどうかを判断します(つまり、現在の温度の値が燃え出す限界値を超えているかを見ます)。
  • Combustion Temperature(発火温度):発火するために必要な温度です。
  • Heatup Rate(加熱速度):他の熱源の半径内にあるときに、どれだけ早くアイテムが加熱されるか を表します。
  • Cooldown Rate(冷却速度):アイテムがどのくらい早く「熱されていない」温度に戻るかを表します。これは、デザインレバーの名前が自己記述的であるならば、保持力、または熱特性と呼ぶことができます。
  • Burn Rate(燃焼速度):時間経過によりアイテムがどのくらい早く燃えるかを表します。
  • Fuel(燃料の量):アイテムが燃える際、どのくらいの燃料に相当するかを表します。
  • Heat Strength(熱の強さ):半径内の熱の強さを表します。
  • Heat Radius(熱の届く半径):熱の届く範囲(拡散範囲)を表します。

これにいくらか補助的なゲームプレイコードを追加すれば、あるオブジェクトの隣にあるオブジェクトが燃える仕組みができます。プロトタイプのプロファイルを保存し、ちょうどいいところを見つけるまで大胆にさまざまな設定を試し、いい値を見つけたら属性で固定しましょう。

Prototyped with assets from the Asset Store
アセットストアのアセットを使用したプロトタイピング

火が水で遮られることを想定した設計はありませんが、水の上に燃えるものがなければ、新たなシステムを追加しない限り、火が反対側に届かなければ延焼することはありません。 

この火炎伝播システムの例では、燃料の量、燃焼速度、熱の強さなどを工夫することで、同じ結果を得るための様々な方法を提供しています。また、例えば燃料の量を「健康度」に置き換えることで、機能性を損なうことなく、木が倒れるタイミングを一定の範囲で制御できるようになるなど、新たな成果を生み出すことができます。木の健康状態が悪くなると、高確率で倒れるようになります。こうすると燃えている木の健康度が低下すると倒れることが起きるシステムができます。木が倒れたのが可燃物がある場所で、このときプレイヤーが管理していないと大混乱に陥ることがあります。 

このように環境にシステムを追加していくと、お互いに反応し合うシステムのエコシステムができあがります。プレイヤーが木材を使ってアイテムの収穫、構築、製作を行うことができ、すべてのアイテムに火の伝播システムが継承されていると仮定すると、気をつけないと大混乱に陥るかもしれません。 

Panel

燃焼温度のしきい値を下げ、加熱速度を上げてオブジェクトがより早く燃え出すようにすれば、あちらこちらで火が出るような火災伝播の構成を作ることができます。半径を大きくすると、より速く、制御できないほどに広がる火災を表現することもできます。加熱速度は、粒度を出すために 0 ~ 50 に制限されています。熱の強さとこの値は掛け合わせることができますが、合理的な範囲にとどめておきたいものです。熱の強さが 4 の場合、加熱速度は 0 〜 200 の範囲にスケールされることになりますが、これはやりすぎで、ほんの数秒で山火事になってしまいます。これではプレイヤーが反応して炎を制御する時間がないので、ゲーム性は高くなりません。

Panel

発火温度のしきい値を 300 に引き上げることで、よりバランスのとれた火炎伝播システムが実現できます。プレイヤーは炎が出る前に他の作業をすることができ、炎が出たときには反応する時間があり、対応が早ければ炎を制御することができます。木を伐採したり、障壁を建設したり、火のシステムと同じくらい体系化されたシンプルな水システムを利用できる能力があればなおさらです。

火の熱の届く半径内にあるオブジェクトに抵抗値を導入することで、火災伝播システムをさらに拡張することができます。これにより、温度差のある火災を発生させることができますし、構造物のアップグレードとして耐火性コーティングを考えることも可能になります。やりすぎかもしれませんが、火のシステムと連動させることで、寒い森の中でプレイヤーが生き延びるための可能性を広げることができる、システマティックなゲームプレイデザインを考えるための一例です。

A very memorable moment Don’t Starve from Klei, when a forest fire breaks out
Kleiの『Don't Starve』でとても印象に残っている、山火事が起きた瞬間のショット

火の伝播システムの例では、直線的な仕組みのアイデアを、ゲームのシステムを学び、理解することでプレイヤーが課題を解決できるような興味深い体験に変えることができることを示しています。また、現実を模倣する必要のないシステムであれば、複雑さや抽象度を高める必要もありません。 

この記事では、この簡単な例をもとに、モジュール化された小さくてシンプルなシステムをどのように設計すれば、ゲームプレイのためのより大きな生態系を作り出すことができるかを探ります。この生態系は、同僚からの意見を参考にして調整し、反復することができるデザインレバーでバランスを取ることができます。これらの要素は、プレイヤーに予想外の楽しさ、喜び、サスペンスをもたらし、ゲームを真にユニークなものにするのに役立ちます。 

Unity でゲームプレイをデザインし、より豊かなものにするための多くのヒント、解説、インスピレーションを、無料の新しい e ブックから学んでください。  

2021年12月7日 カテゴリ: テクノロジー | 10 分 で読めます
取り上げているトピック