Menu
CoddyTech

敵の基本スクリプト

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()は呼び出した位置で基底クラスの処理を実行します。この呼び出しを省略すると、基底クラスの処理はスキップされます。これにより、サブクラスは手順を追加するのではなく、置き換えることができます。

challenge icon

チャレンジ

簡単

モンスターたちが城に向かって行進しています。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;
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

Unityにおけるゲームアーキテクチャのすべてのレッスン