《Unity 3D游戏客户端基础框架》消息系统

功能分析:

首先,我们必须先明确一个消息系统的核心功能:

  • 一个通用的事件监听器
  • 管理各个业务监听的事件类型(注册和解绑事件监听器)
  • 全局广播事件
  • 广播事件所传参数数量和数据类型都是可变的(数量可以是 0~3,数据类型是泛型)

设计思路:

清楚了上述的几个要求之后,我们不难自行定制一个业务层的消息系统,即在消息系统初始化时将每个模块绑定的消息列表,根据消息类型分类(用一个 string 类型的数据类标识),即建立一个字典Dictionary<string,List<Model>> 每条消息触发时需要通知的模块列表,即某条消息触发,遍历字典中绑定的模块列表,然后有两种选择方案:

  • 假如模块是与 gameObject 绑定的继承自 MonoBehaviour 的脚本,通过 Unity 原生的向指定模块发送消息的接口gameObject.SendMessage(message) 发送消息,模块用则用 public void getMessage(string message) 函数接收消息;
  • 假如模块是独立的 C# 实例,则可以给模块设计一个基类,基类中有一个虚构函数,在具体模块中重写这个函数,这样消息中心要想模块发送触发消息时,直接将模块字典中绑定的模块引用强转为基类类型,然后调用该虚构函数。

然而,这样的 DIY 的消息管理系统最常见的问题就是:模块已经销毁了,但在字典中的引用还在,那么消息要传递给模块的时候,就会触发 MissingReferenceException 或者 NullReferenceException 这类空引用错误。

使用方法:

Advanced CSharp Messenger 是一个 C# 高级版本的消息传递系统 。它将会在加载一个新的 level 后自动清理其事件表。这将防止程序员意外地调用被毁坏的方法,从而将有助于防止很多 MissingReferenceExceptions。此消息传递系统基于杆海德 CSharpMessenger 和马格努斯沃尔费尔特的CSharpMessenger 扩展。

核心功能:

1.注册一个事件监听器:

Messenger.AddListener<T>( "消息类型标识", OnCallback);
//事件回调函数
void OnCallback(T data){
   
}

监听事件可以带参也可不带参,参数类型是泛型,既可以传递基础数据类型,也可以传递 gameObject 对象,当然两种情况属于完全不同的时间,用一个字符串来表示事件的类型,OnCallback 是事件出发时的回调函数,回调函数的参数表与监听格式一致。

2.取消注册事件监听器:

这里需要注意的就是与注册时的参数格式完全一致,只是把 AddListener 改成 RemoveListener:

Messenger.RemoveListener<T>( "消息类型标识", OnCallback);

3.广播事件:

//不带参
Messenger.Broadcast( "消息类型标识");
//带参
Messenger.Broadcast<T>( "消息类型标识", data1);

第一个参数是事件类型标识,后面的参数表是与 <T> 中指定的数据类型对应的回传数据。

插件引入:

只需在当前项目组添加一下两个脚本,即可开始使用 Advanced CSharp Messenger 这个消息管理器来管理我们项目的消息了。
Callback.cs

public delegate void Callback();
public delegate void Callback<T>(T arg1);
public delegate void Callback<T, U>(T arg1, U arg2);
public delegate void Callback<T, U, V>(T arg1, U arg2, V arg3);

Messenger.cs

/*
 * Advanced C# messenger by Ilya Suzdalnitski. V1.0
 * 
 * Based on Rod Hyde's "CSharpMessenger" and Magnus Wolffelt's "CSharpMessenger Extended".
 * 
 * Features:
    * Prevents a MissingReferenceException because of a reference to a destroyed message handler.
    * Option to log all messages
    * Extensive error detection, preventing silent bugs
 * 
 * Usage examples:
    1. Messenger.AddListener<GameObject>("prop collected", PropCollected);
       Messenger.Broadcast<GameObject>("prop collected", prop);
    2. Messenger.AddListener<float>("speed changed", SpeedChanged);
       Messenger.Broadcast<float>("speed changed", 0.5f);
 * 
 * Messenger cleans up its evenTable automatically upon loading of a new level.
 * 
 * Don't forget that the messages that should survive the cleanup, should be marked with Messenger.MarkAsPermanent(string)
 * 
 */

//#define LOG_ALL_MESSAGES
//#define LOG_ADD_LISTENER
//#define LOG_BROADCAST_MESSAGE
#define REQUIRE_LISTENER

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

static internal class Messenger
{
   
    #region Internal variables

    //Disable the unused variable warning
#pragma warning disable 0414
    //Ensures that the MessengerHelper will be created automatically upon start of the game.
    static private MessengerHelper messengerHelper = (new GameObject("MessengerHelper")).AddComponent<MessengerHelper>();
#pragma warning restore 0414

    static public Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();

    //Message handlers that should never be removed, regardless of calling Cleanup
    static public List<string> permanentMessages = new List<string>();
    #endregion
    #region Helper methods
    //Marks a certain message as permanent.
    static public void MarkAsPermanent(string eventType)
    {
   
#if LOG_ALL_MESSAGES
        Debug.Log("Messenger MarkAsPermanent \t\"" + eventType + "\"");
#endif

        permanentMessages.Add(eventType);
    }


    static public void Cleanup()
    {
   
#if LOG_ALL_MESSAGES
        Debug.Log("MESSENGER Cleanup. Make sure that none of necessary listeners are removed.");
#endif

        List<string> messagesToRemove = new List<string>();

        foreach (KeyValuePair<string, Delegate> pair in eventTable)
        {
   
            bool wasFound = false;

            foreach 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
UNITY游戏框架原理基于MVC的逻辑模式。MVC是一种在制作游戏时对代码的逻辑化整理的思想。在UNITY开发过程中,许多公司在制作游戏开发项目时都使用了MVC的逻辑模式,即数据模型-视图-控制器。 UNITY游戏框架可以分为三个主要部分。第一部分是游戏开发的基础,包括游戏的架构设计、场景管理和资源管理等。第二部分是网络原理,主要介绍网络通信的原理,开发客户端的网络模块和服务端程序框架。这套框架具有较高的通用性,可用于多种游戏。第三部分是网络游戏,主要讲解房间系统和多人游戏的开发。 在设计UNITY游戏框架时,可以考虑采用MVC的结构模式,将模块之间的功能区分开,达到低耦合的效果。这样做的好处是,当需要替换游戏UI或进行其他功能修改时,只需修改相应的模块,而不会影响到其他功能,提高了游戏质量和开发效率。举个例子,如果一个项目的各个UI下挂载了大量的脚本,替换UI可能会导致其他功能受到影响,而采用MVC的结构模式可以解决这个问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Unity框架——MVC框架](https://blog.csdn.net/Htlas/article/details/79076201)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Unity 3D网络游戏实战](https://download.csdn.net/download/qq_39014199/11143402)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值