unity消息系统机制,工具类可以直接使用

18 篇文章 0 订阅

转自:http://www.manew.com/blog-117699-43032.html

在开发Unity的时候,为了方便开发一般都会采用消息事件,消息事件主要是做啥的?我们如何去封装,如何去运用消息事件处理事情。接下来就给大家介绍一下:

消息事件顾名思义,是通过消息触发的事件。比如大家去完成某个任务,完成后才会触发另一个事件的发生,这种情况我们就会使用消息事件等等吧。

消息事件的使用主要是通过添加消息监听,然后分发消息处理事情。

那我们如何去封装我们的消息系统,在这里我把代码给大家分享一下:

1.首先我们封装消息事件的基类CBaseEvent.cs

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

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

public class CBaseEvent
{

    protected Hashtable arguments;
    protected CEventType type;
    protected object sender;
    protected string eventName;

    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 string EventName
    {
        get
        {
            return eventName;
        }

        set
        {
            eventName = value;
        }
    }

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

    public CBaseEvent Clone()
    {
        return new CBaseEvent(this.type, this.arguments, Sender);
    }

    public CBaseEvent(CEventType type, object sender)
    {
        this.Type = type;
        Sender = sender;
        if (this.arguments == null)
        {
            this.arguments = new Hashtable();
        }
    }

    public CBaseEvent(CEventType type, Hashtable args, object sender)
    {
        this.Type = type;
        this.arguments = args;
        Sender = sender;
        if (this.arguments == null)
        {
            this.arguments = new Hashtable();
        }
    }

    public CBaseEvent(string eventName, object sender)
    {
        this.EventName = eventName;
        Sender = sender;
        if (this.arguments == null)
        {
            this.arguments = new Hashtable();
        }
    }
}

2.以上是消息基类的定义。那接下来就是封装对外使用的消息接口了。写一个新的类CEventDispatcher

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();

    public void AddEventListener(CEventType eventType, CEventListenerDelegate listener)
    {
        CEventListenerDelegate ceventListenerDelegate = this.listeners[eventType] as CEventListenerDelegate;
        ceventListenerDelegate = (CEventListenerDelegate)Delegate.Combine(ceventListenerDelegate, listener);
        this.listeners[eventType] = ceventListenerDelegate;
    }

    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;
    }

    public void AddEventListener(string eventName, CEventListenerDelegate listener)
    {
        CEventListenerDelegate ceventListenerDelegate = this.listeners[eventName] as CEventListenerDelegate;
        //这个combine就相当于委托的+=    (整体的实现就是类似于观察者模式)
        ceventListenerDelegate = (CEventListenerDelegate)Delegate.Combine(ceventListenerDelegate, listener);
        this.listeners[eventName] = ceventListenerDelegate;
    }
    public void RemoveEventListener(string eventName, CEventListenerDelegate listener)
    {
        CEventListenerDelegate ceventListenerDelegate = this.listeners[eventName] as CEventListenerDelegate;
        if (ceventListenerDelegate != null)
        {
            ceventListenerDelegate = (CEventListenerDelegate)Delegate.Remove(ceventListenerDelegate, listener);
        }
        this.listeners[eventName] = ceventListenerDelegate;
    }

    public void DispatchEventOnce(CBaseEvent evt)
    {
        CEventListenerDelegate ceventListenerDelegate;
        if (string.IsNullOrEmpty(evt.EventName))
        {
            ceventListenerDelegate = this.listeners[evt.Type] as CEventListenerDelegate;
        }
        else
        {
            ceventListenerDelegate = this.listeners[evt.EventName] as CEventListenerDelegate;
        }
        if (ceventListenerDelegate != null)
        {
            try
            {
                ceventListenerDelegate(evt);
                if (string.IsNullOrEmpty(evt.EventName))
                {
                    this.listeners.Remove(evt.Type);
                }
                else
                {
                    this.listeners.Remove(evt.EventName);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Concat(new string[]
                {
                    "Error dispatching event ",
                    evt.Type.ToString(),
                    ": ",
                    ex.Message,
                    " ",
                    ex.StackTrace
                }), ex);
            }
        }
    }
    /// 
    /// 使用枚举传递
    /// 
    /// 
    public void DispatchEvent(CBaseEvent evt)
    {
        CEventListenerDelegate ceventListenerDelegate = this.listeners[evt.Type] as CEventListenerDelegate;

        if (ceventListenerDelegate != null)
        {
            try
            {
                ceventListenerDelegate(evt);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Concat(new string[]
                {
                    "Error dispatching event ",
                    evt.Type.ToString(),
                    ": ",
                    ex.Message,
                    " ",
                    ex.StackTrace
                }), ex);
            }
        }
    }

    /// 
    /// 使用字符串传递
    /// 
    /// 
    public void DispatchStringEvent(CBaseEvent evt)
    {
        CEventListenerDelegate ceventListenerDelegate = this.listeners[evt.EventName] as CEventListenerDelegate;

        if (ceventListenerDelegate != null)
        {
            try
            {
                ceventListenerDelegate(evt);
            }
            catch (Exception ex)
            {
                throw new Exception(string.Concat(new string[]
                {
                    "Error dispatching event ",
                    evt.Type.ToString(),
                    ": ",
                    ex.Message,
                    " ",
                    ex.StackTrace
                }), ex);
            }
        }
    }

    public void RemoveAll()
    {
        this.listeners.Clear();
    }
}
3.一共就这2个类就可以了,接下来是使用方法
using UnityEngine;
using System.Collections;

public class TestEvent : MonoBehaviour {

	// Use this for initialization
	void Start () {
        CEventDispatcher.GetInstance().AddEventListener("开始触发", MyTestFunc);
        CEventDispatcher.GetInstance().AddEventListener(CEventType.GAME_WIN, MyTestFunc);
        CEventDispatcher.GetInstance().DispatchEventOnce(new CBaseEvent("开始触发","第一次"));
        CEventDispatcher.GetInstance().DispatchStringEvent(new CBaseEvent("开始触发", "第三次"));
        CEventDispatcher.GetInstance().DispatchEvent(new CBaseEvent(CEventType.GAME_WIN, "事件类型"));



    }
    void MyTestFunc(CBaseEvent evt)
    {
        Debug.Log("触发了该方法:"+ evt.Sender.ToString());
    }

}






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值