Unity消息事件的封装(转)

Unity学了有大半年了,懵懵懂懂,不断试错。自学的难点就是会碰到很多弯路,不知道下一步该怎么学。最近买了一本Unity实战技术的书,书中的知识我感觉都是挺实用,相对于大多数只是教教基础的教程来说。

当Unity工程中模块越多,为了解耦,模块之间的消息传递肯定少不了,下面是一个简单的消息事件的封装。上代码!

事件的基类:

using UnityEngine;
using System.Collections;

public enum CEventType
{
    GAME_OVER,
    GAME_WIN,
    PAUSE,
    ENERGY_EMEPTY,
    GAME_DATA,

}

public class CBaseEvent
{
    protected Hashtable arguments;
    protected CEventType type;
    protected object sender;



    /// <summary>
    /// Type属性
    /// </summary>
    public CEventType Type
    {
        get { return this.type; }
        set { this.type = value; }
    }

    public IDictionary Params//属性
    {
        get { return this.arguments; }
        set { this.arguments = (value as Hashtable); }
    }

    public object Sender//属性
    {
        get { return this.sender; }
        set { this.sender = value; }
    }

    public override string ToString()//重写ToString
    {
        return this.type + "[" + ((this.sender == null) ? "null" : this.sender.ToString()) + "]";
    }


    /// <summary>
    /// 克隆基类的方法
    /// </summary>
    /// <returns></returns>
    public CBaseEvent Clone()
    {
        return new CBaseEvent(this.type, this.arguments, Sender);
    }

    /// <summary>
    /// 三个参数的构造函数
    /// </summary>
    /// <param name="type">类型</param>
    /// <param name="args"></param>
    /// <param name="sender"></param>
    public CBaseEvent(CEventType type, Hashtable args, object sender)
    {
        this.Type = type;
        this.arguments = args;
        this.Sender = sender;
        if (this.arguments==null)
        {
            this.arguments = new Hashtable();
        }
    }

    /// <summary>
    /// 两个参数的构造函数
    /// </summary>
    /// <param name="type"></param>
    /// <param name="sender"></param>
    public CBaseEvent(CEventType type, object sender)
    {
        this.Type = type;
        Sender = sender;
        if (this.arguments==null)
        {
            this.arguments = new Hashtable();
        }
    }
}

这个是事件派发类,包含消息注册、消息移除和消息派发的方法

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


public delegate void CEventListenerDelegate(CBaseEvent evt);

public class CEventDispatcher {

    //做成单例模式
    static CEventDispatcher instance;
    public static CEventDispatcher GetInstance()
    {
        if (instance==null)
        {
            instance = new CEventDispatcher();
        }
        return instance;
    }

    //创建一个哈希表用于存放添加的监听
    private Hashtable listeners = new Hashtable();


    /// <summary>
    /// 添加监听
    /// </summary>
    /// <param name="eventType">事件类型</param>
    /// <param name="listener">监听(委托类型)</param>
    public void AddEventListener(CEventType eventType, CEventListenerDelegate listener)
    {
        //添加监听
        listeners.Add(eventType, listener);


        /*
        //直接将事件类型赋值给表,然后得到他的值
        CEventListenerDelegate ceventListenerDelegate = this.listeners[eventType] as CEventListenerDelegate;


        //把监听添加到委托当中
        ceventListenerDelegate = (CEventListenerDelegate)Delegate.Combine(ceventListenerDelegate, listener);

        //事件(委托)重新赋值给键为eventType的监听
        this.listeners[eventType] = ceventListenerDelegate;
        */
    }

    /// <summary>
    /// 移除监听
    /// </summary>
    /// <param name="eventType"></param>
    /// <param name="listener"></param>
    public void RemoveEventListener(CEventType eventType, CEventListenerDelegate listener)
    {
        /*
        CEventListenerDelegate ceventListenerDelegate = this.listeners[eventType] as CEventListenerDelegate;
        if (ceventListenerDelegate!=null)
        {
            //如果事件(委托存在),则将里面的监听移除
            ceventListenerDelegate = (CEventListenerDelegate)Delegate.Remove(ceventListenerDelegate, listener);
        }
        this.listeners[eventType] = ceventListenerDelegate;
        */

        //移除监听
        listeners.Remove(eventType);
    }

    /// <summary>
    /// 分发事件消息
    /// </summary>
    /// <param name="evt">事件类型</param>
    public void DispatchEvent(CBaseEvent evt)
    {
        //从哈希表里得到事件监听
        CEventListenerDelegate ceventListenerDelegate = this.listeners[evt.Type] as CEventListenerDelegate;

        if (ceventListenerDelegate!=null)
        {
            try
            {
                //如果事件监听不为null,则将参数:事件类型 赋值给委托,由此触发事件函数
                ceventListenerDelegate(evt);
            }
            catch
            {

            }
        }
    }

    public void RemoveAll()
    {
        this.listeners.Clear();
    }
}

在AddEventListener方法和RemoveEventListener方法中,注释的那一段是书本中原文的写法,个人不太理解是什么意思(如果有知道的大神恳请给予指点)。而且用原文写法后,测试不成功。于是乎用添加列表的方法代替了原来一大串代码,结果测试成功。

这个是我自己写的测试类

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

public class Sender : MonoBehaviour {

    // Use this for initialization

    void Start()
    {
        //注册消息
        CEventDispatcher.GetInstance().AddEventListener(CEventType.GAME_WIN, GameWin);

        //传入事件类型和object类型的Sender,如果事件类型匹配消息列表里的值,则触发事件函数
        CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.GAME_WIN, "sender"));
    }





    /// <summary>
    /// 用于测试的事件函数
    /// </summary>
    /// <param name="evt"></param>
    private void GameWin(CBaseEvent evt)
    {
        Debug.Log("Game Win!");
    }

}

这里写图片描述

初步理解了消息事件的封装,若想灵活运用,还是要在项目中多写多试。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值