UnityでのGetComponentとポリモーフィズムを利用した Animal サンプル

広告

1. 概要

本資料では、Unity において抽象クラス Animal を基底に、具体的な実装として Dog クラスおよび Cat クラスを作成します。GameObject にアタッチされたコンポーネントを GetComponent() を使って取得し、ポリモーフィズム(多態性)を活用して各派生クラスの機能(Speak メソッド)を利用する方法を解説します。

2. クラスの構成

2.1 Animal クラス(抽象クラス)

Animal クラスは MonoBehaviour を継承した抽象クラスとして定義し、抽象メソッド Speak() を宣言します。これにより、直接インスタンス化されることを防ぎ、派生クラスでの実装を強制します。

using UnityEngine;

public abstract class Animal : MonoBehaviour
{
    // 抽象メソッド:派生クラスで必ず実装する必要がある
    public abstract void Speak();
}

2.2 Dog クラス

Dog クラスは Animal クラスを継承し、Speak() メソッドをオーバーライドして犬の鳴き声「ワンワン」を出力します。

using UnityEngine;

public class Dog : Animal
{
    public override void Speak()
    {
        Debug.Log("ワンワン");
    }
}

2.3 Cat クラス

Cat クラスも Animal クラスを継承し、Speak() メソッドをオーバーライドして猫の鳴き声「ニャーニャー」を出力します。

using UnityEngine;

public class Cat : Animal
{
    public override void Speak()
    {
        Debug.Log("ニャーニャー");
    }
}

2.4 Test クラス

Test クラスは、同じ GameObject にアタッチされた Animal コンポーネント(Dog または Cat)を GetComponent() を使って取得し、Speak() メソッドを呼び出すサンプルです。

※ 注意: Animal クラスが抽象クラスでない場合は、 [RequireComponent(typeof(Animal))] 属性を使用できますが、、Animal クラスを抽象クラスに変更すると、抽象クラスは直接インスタンス化できず自動追加も行われません。
そのため、Test クラスには [RequireComponent] 属性は付与せず、必ず Dog または Cat などの具体的な Animal の派生クラスが同じ GameObject にアタッチされるように設計してください。

ただし、Testクラスをアタッチする前に、Dogクラスをアタッチすると派生クラスのためエラーになりませんがわかりにくいので推奨されません

using UnityEngine;

public class Test : MonoBehaviour
{
    void Start()
    {
        // 同じ GameObject にアタッチされている Animal(=Dog または Cat)コンポーネントを取得
        Animal animal = GetComponent<Animal>();

        if (animal != null)
        {
            // 取得したコンポーネントに対して、実際のクラス(Dog/Cat)の Speak() が実行される
            animal.Speak();
        }
        else
        {
            Debug.Log("Animal コンポーネントが見つかりませんでした。");
        }
    }
}

3. 使用方法

  1. スクリプトの準備
    上記の各コードをそれぞれ Animal.csDog.csCat.csTest.cs として、プロジェクト内の Scripts フォルダなどに保存します。
  2. GameObject の作成とコンポーネントの追加
    • Unity のシーン上に空の GameObject を作成します。
    • 作成した GameObject に Test スクリプトをアタッチします。
    • 同じ GameObject に必ず Dog または Cat のいずれか、もしくは両方の具体的な Animal 派生クラスのコンポーネントをアタッチしてください。
  3. シーンの再生
    シーンを再生すると、Test クラス内の Start() が実行され、GetComponent() により Dog または Cat のコンポーネントが取得され、各クラスに応じた鳴き声がコンソールに出力されます。

4. [RequireComponent] 属性使用時の注意点(抽象クラスの場合)

4.1 現象

  • エラー発生:
    以前は [RequireComponent(typeof(Animal))] 属性を用いていましたが、Animal クラスを抽象クラスに変更すると、Unity は抽象クラスをコンポーネントとして追加できないため、Test コンポーネントを先にアタッチした際にエラーが発生します。

4.2 理由

  • 抽象クラスの特性:
    抽象クラスは直接インスタンス化できません。
  • RequireComponent の動作:
    [RequireComponent] 属性は、指定された型のコンポーネントが必ず存在するように自動追加を試みますが、抽象クラスはインスタンス化できないため、自動追加が行えず、エラーとなります。

4.3 対処方法

  • RequireComponent 属性の削除:
    Animal クラスが抽象クラスである場合、Test クラスから [RequireComponent(typeof(Animal))] 属性を削除してください。
  • 必ず具体的な派生クラスをアタッチ:
    プロジェクト設計上、GameObject に Dog または Cat といった具体的な Animal の派生クラスが必ずアタッチされるように管理するか、実行時に GetComponent() の結果が Dog や Cat であるかチェックするようにしてください。

この資料を参考に、抽象クラスを利用した Unity のポリモーフィズムと、[RequireComponent] 属性使用時の注意点を理解し、実際のプロジェクトに適切に応用してください。

訪問数 46 回, 今日の訪問数 1回

広告

Unity,継承

Posted by hidepon