Unityイベント活用サンプル資料

~発射・衝突処理をイベントで拡張する~


この資料では、Unityにおけるイベントを用いた発射(Shoot)および衝突(Hit)処理のサンプルを紹介します。
従来の直接的なメソッド呼び出しではなく、イベント駆動型の設計を導入することで、処理の疎結合化や拡張性が向上します。
ここでは、発射時と衝突時にイベントを発行し、複数のリスナー(例:サウンド再生)でそれぞれの処理に反応する実装例を示します。


1. サンプル全体の構成

  1. GameEvents.cs
    • 発射および衝突のイベントを定義するクラス。
    • イベントの発行メソッドを持ち、どのスクリプトからでもイベントを発火できるようにします。
  2. IgaguriGenerator.cs
    • マウスクリックを検知し、いがぐりのPrefabを生成して発射します。
    • 発射直後に発射イベントを発行します。
  3. IgaguriController.cs
    • いがぐりの動作(発射時の力の付与、衝突時の処理)を制御。
    • 衝突時に衝突イベントを発行します。
  4. SoundManager.cs
    • 発射および衝突イベントをリッスンし、サウンド再生などの副次的な処理を行います。

2. 各クラスのコード例と解説

2.1 GameEvents.cs

全体で使用するイベントを定義するクラスです。
ここでは、発射時に方向情報(Vector3)を、衝突時は通知のみのイベントを実装しています。

using System;
using UnityEngine;

public static class GameEvents
{
    // いがぐりが発射されたときのイベント(方向情報付き)
    public static event Action<Vector3> OnIgaguriShot;

    // いがぐりが衝突したときのイベント
    public static event Action OnIgaguriHit;

    // 発射イベントを発行するメソッド
    public static void IgaguriShot(Vector3 direction)
    {
        if (OnIgaguriShot != null)
        {
            OnIgaguriShot(direction);
        }
    }

    // 衝突イベントを発行するメソッド
    public static void IgaguriHit()
    {
        if (OnIgaguriHit != null)
        {
            OnIgaguriHit();
        }
    }
}

解説

  • 静的イベントとして定義しているため、どのスクリプトからも簡単にイベント発火が可能です。
  • 発射時は方向情報を付与し、複数のリスナーがその情報を活用できます。

2.2 IgaguriGenerator.cs

マウスクリックを検出していがぐりのPrefabを生成し、発射処理とイベントの発行を行います。

using UnityEngine;

public class IgaguriGenerator : MonoBehaviour
{
    public GameObject igaguriPrefab;

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            // いがぐりPrefabを生成
            GameObject igaguri = Instantiate(igaguriPrefab);

            // カメラからマウス位置へのレイを作成
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            // 生成したオブジェクトのIgaguriControllerを取得して発射処理を実行
            IgaguriController controller = igaguri.GetComponent<IgaguriController>();
            controller.Shoot(ray.direction * 2000);

            // 発射イベントを発行し、他の処理(例:サウンド再生)へ通知
            GameEvents.IgaguriShot(ray.direction);
        }
    }
}

解説

  • マウスクリックでPrefabを生成し、射出方向をカメラとマウス位置から計算しています。
  • 発射処理の直後、GameEvents.IgaguriShot() によりイベントが発火され、関連するリスナーが処理を行えます。

2.3 IgaguriController.cs

いがぐりの動作を管理するクラスです。
発射時はRigidbodyに力を加え、衝突時には物理を停止しパーティクルエフェクトを再生。
また、衝突時にイベントも発行します。

using UnityEngine;

public class IgaguriController : MonoBehaviour
{
    public void Shoot(Vector3 force)
    {
        GetComponent<Rigidbody>().AddForce(force);
    }

    void OnCollisionEnter(Collision collision)
    {
        // 衝突時に物理演算を停止し、パーティクルを再生
        GetComponent<Rigidbody>().isKinematic = true;
        GetComponent<ParticleSystem>().Play();

        // 衝突イベントを発行
        GameEvents.IgaguriHit();
    }

    void Start()
    {
        Application.targetFrameRate = 60;
    }
}

解説

  • Shootメソッド
    Rigidbodyに対して力を加え、発射を実現します。
  • OnCollisionEnterメソッド
    衝突時に、動作を停止させると同時にパーティクルエフェクトを再生。
    そして、衝突イベントを発行することで、他の処理(例えば、サウンド再生)に通知できます。

2.4 SoundManager.cs

発射および衝突イベントを購読し、それぞれのタイミングでサウンド再生などの処理を実行するクラスです。

using UnityEngine;

public class SoundManager : MonoBehaviour
{
    void OnEnable()
    {
        // 発射および衝突イベントのリスナーとして登録
        GameEvents.OnIgaguriShot += PlayShotSound;
        GameEvents.OnIgaguriHit += PlayHitSound;
    }

    void OnDisable()
    {
        // イベントリスナーの解除
        GameEvents.OnIgaguriShot -= PlayShotSound;
        GameEvents.OnIgaguriHit -= PlayHitSound;
    }

    // 発射イベント受信時の処理
    void PlayShotSound(Vector3 direction)
    {
        Debug.Log("Shot sound played. Direction: " + direction);
        // AudioSource.PlayClipAtPoint(shotClip, transform.position); など実装可能
    }

    // 衝突イベント受信時の処理
    void PlayHitSound()
    {
        Debug.Log("Hit sound played.");
        // AudioSource.PlayClipAtPoint(hitClip, transform.position); など実装可能
    }
}

解説

  • イベント登録は OnEnable()、解除は OnDisable() で行うのが一般的です。
  • 発射や衝突の各イベントに対して、適切なサウンド再生処理を実装できます。
  • これにより、いがぐりの発射や衝突に合わせた副次的な処理が、各スクリプト間の依存を持たずに実現されます。

3. イベント駆動型設計のメリット

  • 疎結合化
    発射や衝突の主要な処理と、サウンド再生・UI更新などの副次的処理が独立して実装できるため、保守性が向上します。
  • 拡張性
    新たなイベントリスナー(例:スコア管理、エフェクト拡張など)を後から容易に追加できます。
  • 柔軟なデバッグ
    イベントを発行するタイミングで、各リスナーの反応を独立して確認・修正できるため、トラブルシューティングがしやすい設計となります。

4. まとめ

本サンプルでは、Unityでの発射と衝突処理に対して、直接的なメソッド呼び出しではなくイベントを活用する方法を紹介しました。

  • GameEvents によるイベント定義で、主要処理と副次処理の分離が実現。
  • IgaguriGeneratorIgaguriController で主要な動作を実装。
  • SoundManager でイベントリスナーを登録し、サウンド再生などの処理を実行。

このようなイベント駆動型の設計は、複雑なゲームシステムや拡張性を求めるプロジェクトで特に有効です。ぜひ、このサンプルをベースにして、独自の機能追加やシステム拡張に挑戦してみてください。

Unity,イベント

Posted by hidepon