技を JSON 1ファイルで定義する ― タイムラインで組み立てる攻撃データ
攻撃の発生タイミング、ダメージ、ヒットストップ、コンボの派生先まで、技に関するすべてを JSON 1ファイルにまとめた設計と、その理由を説明します。
- ゲーム設計
- アクション
- Mod
- データ設計
アクションゲームの「技」には、決めなければならないことが大量にあります。 いつ攻撃判定が出るのか、どれくらい続くのか、ダメージはいくつか、 当たったらどれくらい止まるのか、次にどの技につながるのか。 このプロジェクトでは、それらをすべて JSON のファイル 1つに書くことにしました。
動きとロジックを分ける
技を構成する要素は、大きく2つに分かれます。
- 見た目の動き:キャラクターがどう動くか。アニメーション
- 戦闘のロジック:いつ当たるか、何が起きるか。判定やダメージ
見た目の動きはアニメーションのデータに任せ、 戦闘のロジックはすべて JSON 側が持つ、という分け方をしています。
こうすると、テキストエディタだけで技を作ったり調整したりできるようになります。 ダメージを少し上げたい、発生を少し早めたい、といった調整のために Unity を開く必要がありません。これは Mod 作者にとって特に大きな利点です。 Unity を持っていない人でも、技を作れるからです。
時間はミリ秒で書く
技の中の出来事は、すべて技が始まってからのミリ秒で指定します。 「300 ミリ秒から 400 ミリ秒のあいだ、攻撃判定が出る」という具合です。
アクションゲームの調整は「何フレーム目に発生」とフレーム単位で 語られることが多いのですが、データにはあえてミリ秒を使っています。 フレーム数で書くと、フレームレートが変わったときに意味が変わってしまうからです。 60 フレームのゲームで 1 フレームはおよそ 16.67 ミリ秒なので、 頭の中でフレームに換算するのは難しくありません。
タイムラインで組み立てる
技のデータは、複数のタイムラインを持ちます。 攻撃判定、食らい判定、ガード判定、キャンセル可能区間、無敵区間、移動制御など、 種類ごとにタイムラインが分かれていて、それぞれに 「いつからいつまで」あるいは「いつ」を書いていきます。
攻撃判定のタイムラインには、1つの技に複数の項目を書けます。 つまり、多段ヒットする技は、攻撃判定を複数並べるだけで表現できます。
攻撃判定の1項目には、次のような情報を持たせています。
- 判定が出ている時間の区間
- 判定の位置と大きさ(奥行きの幅も含む)
- どのボーンに追従するか
- ダメージ
- 上段・中段・下段・ガード不能の種別
- ノックバックの向きと強さ
- ヒットストップの長さ
- 当たった相手とガードした相手の、それぞれの硬直時間
- 空中コンボの制限に使う値
- ヒット時の効果音
一見多く感じますが、技の手触りを決めるのはこうした細かい数値です。 これらを一箇所にまとめておくことで、技の性質がファイルを見るだけで分かります。
コンボのつながりもデータで書く
技が終わったあとにどうなるかも、データで指定します。 自動で次の技に移るのか、待機状態に戻るのか。 移動入力でキャンセルできるのか。
コンボの派生も同じです。弱攻撃のあとに強攻撃を入力したら何が出るか、 といったつながりは、キャラクターごとにデータとして定義します。 コードにコンボの組み合わせを書き込まないので、 新しいコンボを追加するのにプログラムを変える必要はありません。
まとめ
技のデータをファイル1つに閉じ込めたのは、技の単位で作り、調整し、 共有できるようにしたかったからです。 1つのファイルを見れば、その技のすべてが分かる。 1つのファイルを差し替えれば、その技が変わる。 この単純さが、Mod で技を作るという体験を支えています。