敵にタイプをつけてみたら、状態が増えて混乱した話
はじめに
前回の記事では、
- 敵を動かした
- プレイヤーを追跡させた
- 当たり判定をつけた
でも、
動いているけど、何が起きているか分からない
という状態でした。
今回はその続きとして、
敵にタイプ(個性)を持たせる処理 を追加しました。
ただ色を変えるだけのつもりが、
思った以上に「状態」が増えて混乱しました。
敵にタイプを持たせてみる
やりたかったことは単純です。
- 敵を3タイプにする
- タイプごとに強さを変える
- 速度も変える
- 色も変える
まずは enum を使ってタイプを定義しました。
public enum EnemyType
{
Red,
Blue,
Yellow
}
そして、プレイヤーを発見した瞬間に
ランダムでタイプを決めるようにしました。
enemyType = (EnemyType)Random.Range(0, 3);
ここまでは、そこまで難しくありませんでした。
タイプごとの違いを作る
タイプごとに、
- 移動速度
- ダメージ
- 色
を変えるようにしました。
switch (enemyType)
{
case EnemyType.Red:
moveSpeed = 1.5f;
damage = 3;
rend.material.color = Color.red;
break;
case EnemyType.Blue:
moveSpeed = 2.5f;
damage = 2;
rend.material.color = Color.blue;
break;
case EnemyType.Yellow:
moveSpeed = 4.0f;
damage = 1;
rend.material.color = Color.yellow;
break;
}
ここまでで、
- 赤は遅いけど強い
- 青は普通
- 黄色は速いけど弱い
という違いを作ることができました。
動いたときは、
ちょっとゲームっぽいかも
と思いました。
でも、ここから混乱した
問題は「いつタイプを決めるか」でした。
今回は、
- プレイヤーを一定距離以内で発見したとき
にタイプを決めるようにしました。
if (!isChasing)
{
if (distSq < chaseDistance * chaseDistance)
{
DecideType();
isChasing = true;
}
}
つまり、
- まだ追いかけていない
- 一定距離に入った
- そこで初めて個性が決まる
という流れです。
ここで初めて、
「状態」というものを意識し始めました。
状態が増えていく感覚
今回のスクリプトには、
- isChasing(追跡中かどうか)
- lostTime(見失い時間)
- enemyType(タイプ)
- プレイヤーの無敵状態(別スクリプト)
など、複数の状態が存在しています。
さらに、プレイヤーと衝突したあとには
リセット処理も入れました。
void ResetEnemy()
{
isChasing = false;
rend.material.color = originalColor;
lostTime = reChaseDelay;
}
ここで、
- 追跡をやめる
- 色を元に戻す
- 一定時間は再追跡しない
という動きをさせています。
正直な感想
動いてはいます。
でも、
今この敵は、どの状態なんだろう?
と聞かれると、少し考えてしまいます。
- ResetEnemy() って本当にこれで全部戻ってる?
- 戻し忘れてるものない?
- なんで sqrMagnitude で比較してるんだっけ?
- 敵が1体ならいいけど、これが10体になったらどうなるんだろう?
コードは書いたのに、
全体像がまだはっきりしていません。
今回少しだけ分かったこと
前回は、
「Unityが何かやっている」くらいの理解でした。
今回は、
- 自分が状態を増やしている
- そのせいで複雑になっている
という実感が少しありました。
動いているかどうかだけでなく、
いま何が起きているのかを説明できるか?
が大事なんだと、少しだけ感じました。
次にやりたいこと
敵に個性を持たせたことで、
少しゲームらしくなりました。
次は、
- 勝敗を表示したい
- ゲームとして区切りを作りたい
と思い、
WIN / LOSE 表示を実装してみました。
また別の場所で混乱しました。
その話を次回書こうと思います。