スポンサーリンク

【Unity】ScriptableObjectを使ってイベントシステムを作る方法

Unity

Unity Version 2021.3.11f1(LTS)

ScriptableObject とは?

ScriptableObjectは、ゲームのデータを格納しておくことが出来るUnity独自のクラスです。ゲーム中のキャラクターのパラメーターを管理するのに使ったり、クラス間のデータの中継をしたりするのに使われます!

今回は、ScriptableObjectを使って、ゲーム中の事象(イベント)を管理する方法を紹介していきます!

例えば、

「プレイヤーが死亡したときに効果音を鳴らす」
「プレイヤーがゴールしたときアニメーションを再生する」
「UIのメニューを閉じたときにゲームを再開する」

などのゲーム中のイベントを、簡単に管理することが出来ます!

イベントを管理するScriptableObject

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


[CreateAssetMenu]
public class GameEvent : ScriptableObject
{
	private List<GameEventListener> listeners =
	new List<GameEventListener>();

	//登録されている関数を実行する
	public void Raise()
	{
		for (int i = listeners.Count - 1; i >= 0; i--)
		{
			listeners[i].OnEventRaised();
		}
	}

	//リスナーを追加する
	public void RegisterListener(GameEventListener listener)
	{
		listeners.Add(listener);
	}

	//リスナーを削除する
	public void UnregisterListener(GameEventListener listener)
	{
		listeners.Remove(listener);
	}
}

このクラスは、ゲームのイベントを管理するScriptableObjectクラスです。

イベントが実行されたときに、登録されているリスナー(GameEventListener)のイベント関数を実行することで、リスナー側にイベントが実行されたことを伝えています。

イベントを受け取る側

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

//イベントのリスナー側
public class GameEventListener : MonoBehaviour
{
    [Header("監視対象のイベント")]
    public GameEvent gameEvent;

    [Header("イベントが起こった時の関数")]
    public UnityEvent response;

    //アクティブ時に呼ばれる
    private void OnEnable()
    {
        gameEvent.RegisterListener(this);

    }

    //非アクティブ時に呼ばれる
    private void OnDisable()
    {
        gameEvent.UnregisterListener(this);
    }

    //登録している関数を実行する
    public void OnEventRaised() 
    {
        response.Invoke();
    }
}

このクラスは、監視対象のイベントを監視して、対象のイベントが実行されたときに、登録されている関数を実行するクラスです。

Inspectorにて、監視をしたいイベントのScriptableObjectを設定して、監視対象のイベントが起こった時に、実行する関数を登録することが出来ます!

サンプルクラス

using UnityEngine;

//プレイヤーテストクラス
public class TestPlayer : MonoBehaviour
{
    public GameEvent deathEvent;    //死亡イベント

    private int _health;    //体力

    //ダメージを与える
    public void Damage(int value) 
    {
        _health -= value;

        //死亡するか
        if (DeathCheck()) 
        {
            Death();
        }
    }

    //死亡チェック
    private bool DeathCheck() 
    {
        //体力が0以下になったら
        return _health <= 0;
    }

    //死亡時の処理
    private void Death() 
    {
        deathEvent.Raise(); //死亡イベントを通知
    }
}

サンプルプログラムでは、プレイヤーが死亡したときにイベントの通知を行っています。

この方法を使えば、効果音を鳴らすクラスや死亡アニメーションを再生するクラスが、プレイヤーの体力をいちいち監視することなく、処理を実行することが出来ます!

まとめ

今回は、ScriptableObjectを使って、イベントシステムを作る方法を紹介しました!

この方法を使えば、プログラムの依存関係が解消されるので、クラスごとの単体テストがやりやすくなります。

ScriptableObjectを使いこなせば、プログラムが見やすくなってバグも減ると思うので、積極的に使ってあげて下さい!

お疲れさまでした!

タイトルとURLをコピーしました