インターフェースを実装することで、自動的にメソッドが実行されるコードのサンプル

2023年11月4日

この学習用サンプルコードは、タイマーシステムで、ゲーム内の任意のオブジェクトに1秒ごとに特定のアクションを実行させることができます。たとえば、キャラクターの状態を定期的に更新したり、時間に基づいてイベントをトリガーしたり、環境の変化を周期的に制御するなどの操作が可能です。これにより、ゲームプレイのダイナミズムとインタラクティビティが向上します。

それでは、早速学習を進めてきましょう

シーン構成

シーンにゲームオブジェクトを1つ作成し、SimpleTimerManagerスクリプトをアタッチします
さらにゲームオブジェクトに作成し、ExampleUsageスクリプトをアタッチします

実行します

スクリプト一覧

using UnityEngine;

public class ExampleUsage : MonoBehaviour, ITimer
{
    public void OnTimer()
    {
        // ここにタイマーが1秒ごとに実行する処理を記述
        Debug.Log($"{gameObject.name}  ExampleUsageのタイマー");
    }
}
using UnityEngine.EventSystems;

interface ITimer : IEventSystemHandler
{
    void OnTimer();
}
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
public class SimpleTimerManager : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(TimerCoroutine());
    }

    IEnumerator TimerCoroutine()
    {
        while (true)
        {
            GameObject[] allObjects = FindObjectsByType<GameObject>(FindObjectsSortMode.None);

            foreach (var obj in allObjects)
            {
                ExecuteEvents.Execute<ITimer>(obj, null, (receiver, eventData) => receiver.OnTimer());
            }
            yield return new WaitForSeconds(1);
        }
    }
}

解説

コードはタイマーシステムを構築します。ITimerインターフェースはタイマーイベントを処理するOnTimerメソッドを持ちます。ExampleUsageクラスはこのインターフェースを実装し、OnTimer内でログ出力を行います。SimpleTimerManagerはコルーチンを使い、1秒ごとにシーン内の全GameObjectでITimerのOnTimerを実行させます。これにより、定期的なアップデートを容易に実装できます。

ExampleUsage

このスクリプトは ExampleUsage という名前のクラスを定義しており、MonoBehaviour という基本クラスを拡張し、ITimer というインターフェイスを実装しています。このクラスは、Unityでのタイマー機能を示しています。

詳細を見ていきましょう:

  • using UnityEngine;: Unityエンジンの機能にアクセスするために必要な名前空間をインポートしています。
  • public class ExampleUsage : MonoBehaviour, ITimer: ExampleUsage という新しい公開クラスを定義しています。このクラスは MonoBehaviour を継承しており、これによりUnityのゲームオブジェクトにアタッチすることができます。また、ITimer というインターフェイスも実装していますが、このインターフェイスが何を定義しているかはこのコードからは分かりません。
  • public void OnTimer(): ITimer インターフェイスの OnTimer メソッドを実装しています。これは公開メソッドで、タイマーがトリガーされたときに呼び出されると推測されます。
  • // ここにタイマーが1秒ごとに実行する処理を記述: コメントは、この部分に1秒ごとに実行したい処理を記述することを示しています。
  • Debug.Log($"{gameObject.name} ExampleUsageのタイマー");: デバッグログにメッセージを出力しています。gameObject.name は、このスクリプトがアタッチされているゲームオブジェクトの名前を参照し、ExampleUsageのタイマー は単にログに表示される静的なテキストです。

このコードの意図は、特定のゲームオブジェクトにタイマー機能を提供し、1秒ごとに特定のアクション(この例ではデバッグログの出力)を実行することです

ITimer

このコードは、 ITimer という名前のインターフェイスを作成しており、これは IEventSystemHandler という既存のUnityインターフェイスを継承しています。

詳細について説明します:

  • using UnityEngine.EventSystems;: Unityのイベントシステムに関連する機能へのアクセスを可能にするために、必要な名前空間をインポートしています。
  • interface ITimer : IEventSystemHandler: ITimer という新しいインターフェイスを定義しています。このインターフェイスは IEventSystemHandler を継承しています。IEventSystemHandler はUnityのイベントシステムで使用される基本インターフェイスで、様々なイベントハンドリングのインターフェイスがこれを継承します。
  • void OnTimer();: ITimer インターフェイスに OnTimer というメソッドのシグネチャを定義しています。このメソッドは戻り値を持たず、引数も取りません。ITimer インターフェイスを実装するクラスは、この OnTimer メソッドを具体的に実装する必要があります。

このインターフェイスの目的は、タイマーイベントを処理するための共通の方法を提供することです。Unityのゲームオブジェクトやコンポーネントがこの ITimer インターフェイスを実装すると、特定のタイミングで OnTimer メソッドが呼び出されるように設計することができます。ただし、このコード自体にはタイマーイベントがいつ、どのように発生するかについての詳細は含まれていません。それは ITimer インターフェイスを実装するクラスやシステムの責任となります。

SimpleTimerManager

このコードは、簡単なタイマーマネージャーを実装しています。この SimpleTimerManager クラスは MonoBehaviour を継承しており、ゲームオブジェクトにアタッチして使用することができます。

コードの内容を詳しく見ていきましょう:

  • Start(): Unityのライフサイクルメソッドの一つで、ゲームオブジェクトが有効化されたときに一度だけ呼び出されます。このメソッド内で TimerCoroutine というコルーチンを開始しています。
  • IEnumerator TimerCoroutine(): コルーチンは、独自の実行フローを持つ特殊なメソッドです。このコルーチンは無限ループを使用しており、その中で特定の処理を繰り返します。
  • while (true): 無限ループを表しており、中断されるまで何度も処理を繰り返します。
  • GameObject[] allObjects = FindObjectsByType<GameObject>(FindObjectsSortMode.None);: シーン内のすべてのゲームオブジェクトを取得しています。ただし、FindObjectsByType メソッドは 新しいメソッドで、シーン中でクラスを検索し配列に代入して戻す機能があります
  • foreach (var obj in allObjects): 取得したすべてのゲームオブジェクトに対してループ処理を行います。
  • ExecuteEvents.Execute<ITimer>(obj, null, (receiver, eventData) => receiver.OnTimer());: ITimer インターフェイスを実装しているコンポーネントがあるゲームオブジェクトに対して、OnTimer メソッドを実行します。これは Unity のイベントシステムを使用して、特定のインターフェイスに対するメソッドを呼び出しています。
  • yield return new WaitForSeconds(1);: 1 秒待機し、その後でループの次のイテレーションに進みます。この待機は、コルーチンが特有の yield キーワードを使って行われます。

このクラスの目的は、シーン内のすべてのゲームオブジェクトを繰り返し確認し、ITimer インターフェイスを実装しているものに対して1秒ごとに OnTimer メソッドを実行することです。これにより、タイマーイベントを必要とする機能やコンポーネントに対して、定期的な更新の機会を提供します。

参考

InterfaceRT

Unity

Posted by hidepon