U3D游戏开发框架——消息系统

Posted Hello Bug.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了U3D游戏开发框架——消息系统相关的知识,希望对你有一定的参考价值。

一:目的

为什么要使用消息系统呢,假如我们的游戏中现在有一个敌人和一个玩家,当敌人击中玩家后玩家需要执行自身的扣血操作,那么就需要在敌人类中引用玩家脚本,这样就造成了代码的耦合,消息系统在开发中是一个非常重要的系统,他的作用就是解耦合
Unity提供的消息机制SendMessage可以非常方便我们的脚本开发,但它实现的是一种伪监听者模式,利用的是反射机制,比较低效,几乎不会有人在项目中使用Unity内置的SendMessage,一般都自己去实现一套消息系统


二:解决的问题及优点

——解耦合


三:使用方法

——消息发送方实现接口IMsgHandler
——实现IMsgHandler接口中的getHandlerId(此消息处理器id)和InitHandleMethod方法(添加处理的方法)
——在类初始化和销毁时分别注册和注销消息处理器
——发送消息时直接调用MsgSystem.SendMgr("消息处理器id", "方法id", 任意数量的参数);

using System.Collections.Generic;
using UnityEngine;

public class SenderTest : MonoBehaviour, IMsgHandler
{
    public string getHandlerId => "SenderTest";

    private void Awake()
    {
        MsgSystem.RegisterHandler(this);
    }

    public void InitHandleMethod(Dictionary<string, MsgHandleMethod> handleMethodMap)
    {
        handleMethodMap.Add("Test", Test);
    }

    public void Test(object[] o)
    {
        int p1 = ((int)o[0]);
        Debug.Log(p1);
    }

    private void OnDestroy()
    {
        MsgSystem.UnregisterHandler(this);
    }
}

四:代码实现

using UnityEngine;
using System.Collections.Generic;

/// <summary>
/// 处理的方法
/// </summary>
public delegate void MsgHandleMethod(object[] o);
/// <summary>
/// 消息处理器接口
/// </summary>
public interface IMsgHandler
{
    string getHandlerId { get; }//消息处理器id
    void InitHandleMethod(Dictionary<string, MsgHandleMethod> handleMethodMap);//注册此消息处理器要处理的方法
}

/// <summary>
/// 消息处理器
/// </summary>
public class MsgHandler
{
    public IMsgHandler handler;//消息处理器
    public Dictionary<string, MsgHandleMethod> handleMethodMap;//此消息处理器要处理的方法

    public MsgHandler(IMsgHandler handler)
    {
        this.handler = handler;
        handleMethodMap = new Dictionary<string, MsgHandleMethod>();
        handler.InitHandleMethod(handleMethodMap);
    }
}

/// <summary>
/// 消息系统
/// </summary>
public class MsgSystem
{
    static Dictionary<string, MsgHandler> handlerMap = new Dictionary<string, MsgHandler>();//所有的消息处理器

    /// <summary>
    /// 注册消息处理器
    /// </summary>
    public static void RegisterHandler(IMsgHandler handler)
    {
        string handlerId = handler.getHandlerId;
        if (handlerMap.ContainsKey(handlerId))
        {
            Debug.LogError(string.Format("已经注册此消息处理器:{0}", handlerId));
            return;
        }
        handlerMap.Add(handlerId, new MsgHandler(handler));
    }

    /// <summary>
    /// 注销消息处理器
    /// </summary>
    public static void UnregisterHandler(IMsgHandler handler)
    {
        string handlerId = handler.getHandlerId;
        if (!handlerMap.ContainsKey(handlerId))
        {
            Debug.LogError(string.Format("没有注册此消息处理器:{0}", handlerId));
            return;
        }
        handlerMap.Remove(handlerId);
    }

    /// <summary>
    /// 发送消息
    /// </summary>
    public static void SendMgr(string handlerId, string methodId, params object[] p)
    {
        if (!handlerMap.ContainsKey(handlerId))
        {
            Debug.LogError(string.Format("没有注册此消息处理器:{0}", handlerId));
            return;
        }
        MsgHandler handler = handlerMap[handlerId];
        if (!handler.handleMethodMap.ContainsKey(methodId))
        {
            Debug.LogError(string.Format("消息处理器{0}中没有注册此方法:{1}", handlerId, methodId));
            return;
        }
        handler.handleMethodMap[methodId]?.Invoke(p);
    }
}

 

以上是关于U3D游戏开发框架——消息系统的主要内容,如果未能解决你的问题,请参考以下文章

2022-02-11 U3D全栈班 002-Unity游戏结构和游戏开发流程

U3D编译Web PC IOS Android平台游戏和运行方法

U3D编译Web PC IOS Android平台游戏和运行方法

U3D+ET5.0 网络战棋游戏开发

U3D:如何使用collision pipeline提升游戏开发优势

c# socket select 模型代码(u3d)