RPGのバトル画面を作ろう（２）

さて、前回は超簡易的な画面モックまで作りました。
ここから割とプログラマが苦手な「設計」をしながら続きをしていこうと思います。
目標は「仕様変更にある程度耐えられる」システムになることです。

---

# 振り返り

さて、前回作ったロジックは簡単に言うとこのような感じです。
![RPGのバトル画面を作ろう（２）_01.gif](https://qiita-image-store.s3.amazonaws.com/0/80680/16435076-df1b-5fa9-de2e-e75b57f0259e.gif)

## 問題

至極単純なロジックで動いていますが、このまま作り続けていくには問題があります。

なぜかって？

そう、それは世の中のエンジニア殺しの最強呪文「仕様変更！！」に耐えられないからです。

## 仕様変更について

よく仕事であることなのですが、
前日までは「こんな感じで問題ないです！」と息巻いていたプランナーも、翌日にはこんなことを言ってきます。

- 「行動選択してから実際のアクションまでの時間を遅延させたい（待機モーションを入れたい）」
- 「○○というキャラクターだけ特殊行動をさせたい」
- 「敵がカウンターをしてくるようにしたい」

等など。

1. プランナー「仕様変更！！」
1. エンジニア「なんで今頃言うの！？Σ(ﾟдﾟ；)」

は、最早業界の風物詩です。

今回のように"作りながら考える"ケースは往々にして状況網羅ができなくなることが多いかと思います。
実際僕は今、趣味でこれを作っているのであんまり深く考えていません(￣▽￣;)

自分で作っていてもこの辺が避けられないと割と苦労するので、今回は昔からのRPGによくあるものには対応できるように作っていきたいと思います。

# 行動を制御するシステム

さて、現状は

1. ボタンを押したら
1. 味方が動いて
1. 敵が動く（350ダメージ！などの表記が出る）

という簡単なものです。

この考え方からすると、行動を司るシステムは「Attackボタン」となります。

| 画像 | 解説 |
|:-----------|:-------------|
|![RPGのバトル画面を作ろう（２）_02.png](https://qiita-image-store.s3.amazonaws.com/0/80680/ebb0fdf3-936c-421a-036c-a06bc826ab36.png)|味方キャラが行動してから<br>敵キャラクターがする<br>という流れの原因となったのは<br>"Attack"というボタン|

そのためシステム全体からすると、この"Attack"ボタンは下記の保証をしなくてはならなくなります。
1. 行動入力から味方キャラクターのアニメーション制御
2. 味方キャラクターの行動による敵キャラクターの行動制御
3. 敵キャラクターの行動制御による敵キャラクターのアニメーション制御
4. バトルシステムへの「1ターン」が終わったことの通知

簡単に四行で書きましたが、このままだと随分ヒドいシステムです。
なぜなら、現在において「どんな味方キャラクターが登場して」「どんな敵キャラクターが存在して」「どのようなバトル攻防が繰り広げられるのかwktk」の重要部分が確定していないからです。
そのため、最初のうちはちょっとした仕様変更に耐えられるのですが、塵も積もれば...でリリースする前くらいには既に鬼のようなゴリゴリのコードで作られた「とんでもない」システムになることが容易に予想されます。
※一発作りきりの場合はこれでも頑張れます。リリースしてしまえばメンテナンスがいらないからです。

# システムの保証について

一つのシステムを作るとき、システムには「行動の保証」または「責任と役割」が必要になります。

家電販売店には「商品を供給する」「商品内容の説明と品質を保証する」という役割があります。
電気会社には「電力を供給する」「代金が払われる限り永続的に契約を行使する」という役割があります。
冷蔵庫には「モノを冷やす」「電気が供給されている限り稼動し続ける」という役割があります。
（他に良い例えが思いつかなかった...）

故に

冷蔵庫だけあってもモノを冷やすことはできず
電気がなければ家電販売店で商品を購入することもなく
家電販売店がなければ冷蔵庫が手に入りません。

このように会社や仕事内容が異なっても、そこに関連性があって「システム」が成り立っています。
サービスとしてエンジニアが作成するシステムも同じです。
関連性を考慮してこそ、「設計」と言えるでしょう。

# 保障の切り分け

というわけで、現状は"Attack"ボタンが1ターンを保証しているのですが、少し分散してみました。

![RPGのバトル画面を作ろう（２）_03.gif](https://qiita-image-store.s3.amazonaws.com/0/80680/c4572c54-a068-8372-1274-52c05669b7c2.gif)

【ポイント】

- "Attack"ボタンは入力された情報から必要なデータを"タイムテーブルシステム"へ渡す
  - 「どのキャラクターが」「なんのコマンド」を入力したかがこれに当たります。（まほうでもリミットブレイクでもなんでも良いです）
- タイムテーブルは全ての入力にたいして時間的な制御を行う
  - 味方の行動も敵の行動も必ずこのシステムで管理します。そうしないと「いつ」「だれが」「何を」するのかの管理が複雑になってしまい、開発者泣かせなシステムになってしまいます。
- タイムテーブルは時間が来たら、キャラクターにアニメーションをするように依頼する。

と、一旦はこんな感じのイメージで良いと思います。
こうすることで、

- UI（ユーザーインターフェース）はユーザーからの入力を管理するシステム
- タイムテーブルは時間を管理し、時間になったら他システムに移譲するシステム

と切り分けることができます。
これが責任と役割を分散する作業となります。（ゲーム以外でもよく使用するかと思います。）

# やってみた結果

今回も練習がてら動画付き。↓クリックできるよー

[![バトルシステム作成2](http://img.youtube.com/vi/jCiSjSed2LQ/0.jpg)](http://www.youtube.com/watch?v=jCiSjSed2LQ)

見た目の変化は地味～ですが、これをこの段階で仕込んでおくと後で夢が膨らみます。

# 膨らむ夢

また、これの副産物として後々にこういうことが扱いやすくなります。

![RPGのバトル画面を作ろう（２）_04.png](https://qiita-image-store.s3.amazonaws.com/0/80680/0743e1cb-90b8-0ced-ebbe-ad935172d388.png)

バトル中にキャラが喋るとか、燃えますよね゜+.(・∀・)゜+.゜


# 後書き

今回発生した問題

  - Unityのメインスレッド・サブスレッドについて改めて理解が必要だった。
    - "UnityではThreadクラス内でUnityEngineを使用してはならない"（というかできない）制約があります。
    - そのため、Unityオブジェクトを使用せずにコマンドの状態遷移を行う必要があったので少し時間を食いました。
    - →今度改めて解説でもしようかな。。。

といったところです。
今回はここまで～