Unity学习笔记--C#事件系统的实现与应用

前言

该事件系统由C#的委托进行实现。
关于事件系统的概述和委托的使用可以看其他文章或者官方文档,这里不多说,直接上代码

EventSystem定义

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

namespace Util
{
    
    
    public class EventData
    {
    
    
        //key:变量名字,value:变量值
        public Dictionary<string, object> parms {
    
     get; private set; }
        public EventData(Dictionary<string, object> parms_in)
        {
    
    
            parms = parms_in;
        }
    }

    public static class EventSystem
    {
    
    
        //key:事件名字,value:注册该事件的所有函数
        private static Dictionary<string, Action<EventData>> event_dict = new Dictionary<string, Action<EventData>>();

        public static void AddEventListener(string event_type, Action<EventData> cb)
        {
    
    
            if (event_dict == null)
            {
    
    
                throw new Exception("EventSystem.event_dict is null");
            }
            Action<EventData> action = null;
            event_dict.TryGetValue(event_type, out action);
            action += cb;
            event_dict[event_type] = action;
        }

        public static void RemoveEventListener(string event_type, Action<EventData> cb)
        {
    
    
            if (event_dict == null)
            {
    
    
                throw new Exception("EventSystem.event_dict is null");
            }
            Action<EventData> action = null;
            if(event_dict.TryGetValue(event_type, out action))
            {
    
    
                action -= cb;
                event_dict[event_type] = action;
            }
            else
            {
    
    
                throw new Exception($"EventSystem.event_dict is not have key : {
      
      event_type}, {
      
      cb.Method}");
            }
        }

        public static void Dispatch(string event_type, EventData event_data = null)
        {
    
    
            if (event_dict == null)
            {
    
    
                throw new Exception("EventSystem.event_dict is null");
            }
            Action<EventData> action = null;
            if (!event_dict.TryGetValue(event_type, out action))
            {
    
    
                throw new Exception($"EventSystem.event_dict is not have event : {
      
      event_type}");
            }
            action.Invoke(event_data);
        }
    }

}

应用场景

  1. 游戏刚开始的时候进行初始化操作。
  2. 现在假设玩家有多种状态,比如Win和Dead。当玩家处于不同状态的时候,需要播放指定音效,并且UI要更新。

注册事件

  • PlayerState.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace State
{
    
    
    public enum PlayerState
    {
    
    
        Win,
        Dead
    }
}


下方代码中的 Singleton 是我自己写的单例模板类
具体可以看我之前写的文章:浅谈设计模式和其Unity中的应用:一、单例模式

  • AudioManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Util;
using State;

public class AudioManager : Singleton<AudioManager>
{
    
    
    private void Awake()
    {
    
    
        EventSystem.AddEventListener("GameStart", GameStartPlayAudio);
        EventSystem.AddEventListener("PlayerStateChange", PlayerStateChange);
    }

    private void GameStartPlayAudio(EventData ed)
    {
    
    
        print($"AudioManager : GameStartPlayAudio, ed = {
      
      ed}");
    }

    private void PlayerStateChange(EventData ed)
    {
    
    
        PlayerState player_state = (PlayerState)ed.parms["PlayerCurrentState"];
        switch (player_state)
        {
    
    
            case PlayerState.Win:
                print("WinAudio");
                break;
            case PlayerState.Dead:
                print("DeadAudio");
                break;
        }
    }
}

  • UIManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Util;
using State;

public class UIManager : Singleton<UIManager>
{
    
    
    private void Awake()
    {
    
    
        EventSystem.AddEventListener("GameStart", GameStartPlayUI);
        EventSystem.AddEventListener("PlayerStateChange", PlayerStateChange);
    }

    private void GameStartPlayUI(EventData ed)
    {
    
    
        print($"UIManager : GameStartPlayUI, ed = {
      
      ed}");
    }

    private void PlayerStateChange(EventData ed)
    {
    
    
        PlayerState player_state = (PlayerState)ed.parms["PlayerCurrentState"];
        switch (player_state)
        {
    
    
            case PlayerState.Win:
                print("WinUI");
                break;
            case PlayerState.Dead:
                print("DeadUI");
                break;
        }
    }
}

抛事件

这里简单一点,在Update中按键模拟玩家状态的转换

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Util;
using State;

public class GameManager : Singleton<GameManager>
{
    
    
    private void Start()
    {
    
    
        EventSystem.Dispatch("GameStart");
    }
    
    private void Update()
    {
    
    
        if (Input.GetKeyDown(KeyCode.W))
        {
    
    
            EventData ed = new EventData(new Dictionary<string, object>()
            {
    
    
                {
    
     "PlayerCurrentState", PlayerState.Win },
            });
            EventSystem.Dispatch("PlayerStateChange", ed);
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
    
    
            EventData ed = new EventData(new Dictionary<string, object>()
            {
    
    
                {
    
     "PlayerCurrentState", PlayerState.Dead },
            });
            EventSystem.Dispatch("PlayerStateChange", ed);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_52855744/article/details/130546244