こんにちは、皆さんアクションゲームって知っていますか?
マリオみたいなゲームですね。
ルールがわかりやすいことから初めてゲームを作るときはよく題材に挙げられます。
マリオ自体は、ジャンプしてブロックをこわして、敵を踏みつけるだけのゲームなのでそこまで難しいことはありません
ですがはじめてのひとが、ゼルダのようないろいろな種類の攻撃を使い分けて敵を倒していくゲームを作るとなると至難の業になります。
ここで難しい点は、多彩なアクションを効率よく発生できるようにする設計方法です。
たとえば、剣を振るだけでも以下のような動きになります。
・抜刀のアニメーションを行う。 ・剣を振るアニメーションを行う。 ・剣を振っている間に、一定の間隔で剣先から当たり判定コリジョンを生成する。 ・剣を振り終わったら当たり判定コリジョンを消去する。
この一連の流れをアニメーションのイベントと今回は呼ぶことにします。このようなイベントの流れを汎用的に設定できる設計が必要になります。今回はアクションゲームでのイベント設計の考え方を簡単に説明しようと思います。
シンプルにあつかう。
アニメーションのイベントをシンプルに扱うと以下のように言えると思います。
アニメーションの時系列に沿って、対象の動作を行う。
つまりは、あるイベントを時間が来たら実行するという意味です。
先程の攻撃の流れで剣を振るときのアニメーションに沿ってざっと書いてみたいと思います。
・0フレーム目で抜刀のエフェクトを発生 ・1フレーム目でプレイヤーから見て(1,1)の地点に当たり判定コリジョンを発生 ・3フレーム目でプレイヤーから見て(0,1)の地点に当たり判定コリジョンを発生 ・5フレーム目でプレイヤーから見て(-1,1)の地点に当たり判定コリジョンを発生 ・5フレーム目で剣の軌跡のエフェクトを発生
このように、時系列とイベントの組み合わせができれば、剣で攻撃するというアクションは成立するわけです。
※ 当たり判定のコリジョンをどう扱うかは今後解説していきたいと思います。
では実際に実装するときはどうなるのでしょうか?
データ駆動によるアプローチ
以前、データ駆動によるUnityのゲーム開発について記事で触れさせていただきました。詳しい、データ駆動導入の動機はこちらを参照してください。
tkymx83.hatenablog.com
つまりは、一連の動作の流れをデータとして考えるわけです。
アクションの設定を書いたテキストファイルがあったとします。
0 PlayEffect frash.prefab 1 Collision 1 1 10 3 Collision 0 1 10 5 Collision -1 1 10 5 PlayEffect finish.prefab
これは、1つ目の要素がフレーム数を表していて、2つ目がイベントの種類、それ以降がイベントのパラメータを表しています。
実際のゲームでは、攻撃を放つときにアニメーションとともに、設定ファイルの上から順に対象のフレームでイベントを実行するだけで攻撃を表現することができます。
このように、攻撃時のアニメーションの流れを外出ししておくことで、攻撃を行いたいときにそのファイルを読み込むだけでバラエティーに富んだ攻撃ができるというわけです。
このシステムを作っていれば、例えば別の技を作ってコンボ攻撃を作りたいとなったときも、連続してファイルを読み込んで、はじめの攻撃が終わったタイミングで、次の技を出すと言った動きができれば、
無限のバリエーションをとくることができるようになります。
データとして残す方法は様々
今回はスペース区切りのテキストで残しましたが、いろいろな残し方があります。
xml
html のようにタグをつかって、値とその意味を記述できるデータ構造です。
タグを使うことで要素の組み合わせや順番に意味をもたせることができるため、多様な表現ができます。
ScriptableObject
これはUnity の機能で自分でデータ構造を作ることができ、Unity上から SerializeField をいじるように値の設定ができます。
Unity に親和性があり、型指定をして値の入力ができます。
まとめ
今回はアクションゲームでキャラクタのアクションのイベントの管理をどうするのかを話してきました。
ゲームは基本的に量産に耐えられるために、データ駆動の仕組みにしていくことが多いです。
データ駆動は決まった形式の中で自由に記述する形なので対象融通がきかない面もあります。
しかし、シンプルでもこのような設計をしておくことで、のちのち簡単にコンテンツを追加することができるのでおすすめです。