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

文章介绍了一个基于C#委托实现的Unity事件系统,用于在游戏场景中处理如玩家状态变化等事件。AudioManager和UIManager通过注册事件监听玩家状态改变,根据状态播放相应音效和更新UI。GameManager则负责触发事件,如游戏开始和玩家状态切换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

该事件系统由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);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就一枚小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值