敵の基本スクリプト
CoddyのUnityジャーニー「Unityにおけるゲームアーキテクチャ」セクションの一部。レッスン 2/50。
敵はコードの大部分を共有します。ヒットポイント、速度、移動方法などです。そのコードはMonoBehaviourを継承する基底クラスに置くことができ、敵の種類ごとのクラスはそこから派生します。このEnemyはStartでヒットポイントを設定し、Updateで向いている方向に歩きます。一方、GhostはStartを変更して、2倍の速さで移動します。
public class Enemy : MonoBehaviour
{
public int maxHp = 3;
public float speed = 2f;
protected int hp;
protected virtual void Start()
{
hp = maxHp;
}
protected virtual void Update()
{
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
}public class Ghost : Enemy
{
protected override void Start()
{
base.Start();
speed *= 2f;
}
}Ghostはフィールドを継承するため、InspectorにはGhostのmaxHpとspeedが表示されます。また、Updateも継承するため、独自のUpdateがなくても歩きます。hpはprotectedなので、Enemyとそのサブクラスからは使用できますが、ほかのスクリプトからは使用できません。
Unityはアクセス修飾子に関係なく、名前でStartとUpdateを見つけ、最も派生したクラスにあるものを呼び出します。EnemyのStartがprivateなvoid Start()で、Ghostが独自のStartを宣言していた場合、UnityはGhostのものだけを呼び出します。Enemyのものは実行されず、エラーも出ないままhpは0のままになります。基底クラスのメッセージをprotected virtualと宣言すれば、これは通常のC#の仕組みになります。サブクラスはoverrideを記述し、base.Start()は呼び出した位置で基底クラスの処理を実行します。この呼び出しを省略すると、基底クラスの処理はスキップされます。これにより、サブクラスは手順を追加するのではなく、置き換えることができます。
チャレンジ
簡単モンスターたちが城に向かって行進しています。Enemy.cs には共通の処理が書かれています。Start は hp に maxHp を設定して spawnPoint を記録し、Update は speed の速さでモンスターを z 軸に沿って進ませます。Grunt は単純な Enemy で、正常に動作します。2 種類のモンスターはそれぞれ独自の処理を追加していますが、Enemy の処理が実行されなくなっています。
Golem: Start によってゴーレムは 1.5 倍の大きさになり、The golem wakes upとログに出力されますが、Unity は Golem の Start を実行し、Enemy の Start は実行しないため、hpは 0 のままです。Wasp: Update によってspawnPoint.xの左右 1 ユニットの範囲で動きますが、Unity は Wasp の Update を実行し、Enemy の Update は実行しないため、その場でジグザグに動きます。
Enemy の Start と Update を protected virtual にし、Golem と Wasp でそれらをオーバーライドして、各自の処理の前に Enemy の処理を実行するようにしましょう。Play を押してから、Check を押してください。
自分で試してみよう
using UnityEngine;
// すべてのモンスターに共通するもの。
public class Enemy : MonoBehaviour
{
public int maxHp = 4;
public float speed = 1.5f;
protected int hp;
protected Vector3 spawnPoint;
void Start()
{
hp = maxHp;
spawnPoint = transform.position;
}
void Update()
{
// z軸に沿って城へ進軍する
transform.position += Vector3.back * speed * Time.deltaTime;
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。