Unity框架学习--5 事件中心管理器

这篇具有很好参考价值的文章主要介绍了Unity框架学习--5 事件中心管理器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作用:访问其它脚本时,不直接访问,而是通过发送一条“命令”,让监听了这条“命令”的脚本自动执行对应的逻辑。

原理:
1、让脚本向事件中心添加事件,监听对应的“命令”。
2、发送“命令”,事件中心就会通知监听了这条“命令”的脚本,让它们自动执行对应的逻辑。

Unity框架学习--5 事件中心管理器,unity,unity

 Unity框架学习--5 事件中心管理器,unity,unity

事件中心管理器:添加事件、发送命令

员工类   将方法注册进事件中心管理器

public class Cube : MonoBehaviour
{

    private void Awake()
    {
        EventCenterManager.Instance.AddListener("开工", Write);
    }

    public void Write()
    {
        transform.position += Vector3.right;
        Debug.Log("我是策划,我在写策划案");
    }
}

事件管理中心类

public class EventCenterManager : SingletonPatternBase<EventCenterManager>
{
    //键表示命令的名字
    //值表示命令具体要执行的逻辑
    Dictionary<string, UnityAction> eventsDictionary = new Dictionary<string, UnityAction>();

    public void AddListener(string key,UnityAction call)
    {
        if (eventsDictionary.ContainsKey(key))
        {
            eventsDictionary[key] += call;
        }
        else
            eventsDictionary.Add(key, call);
    }

/// <summary>
    /// 取消监听的命令
    /// </summary>
    public void RemoveListener(string key,UnityAction call)
    {
        if (eventsDictionary.ContainsKey(key))
        {
            eventsDictionary[key] -= call;
        }
    }

    //发送命令
    public void DisPatch(string key)
    {
        if (eventsDictionary.ContainsKey(key))
        {
            eventsDictionary[key]?.Invoke();
        }
    }

想要调用方法就直接DIsPatch  命令名  调用

Stopwatch类测试性能

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// Stopwatch类的工具类,用于计算运行一段代码所用的时间
/// </summary>
public class StopwatchUtility
{
    /// <summary>
    /// 获取执行一段代码所需要的时间
    /// </summary>
    /// <param name="call"></param>
    /// <returns></returns>
    public static TimeSpan GetTime(UnityAction call)
    {
        //声明一个计数器
        Stopwatch timer = Stopwatch.StartNew();

        //开启计时器
        timer.Start();

        //要测试什么代码就将代码放在这里
        call?.Invoke();


        //停止计时器
        timer.Stop();

        //返回时间信息
        return timer.Elapsed;

    }

    public void PrintTime(UnityAction call)
    {
        UnityEngine.Debug.Log(GetTime(call));
    }
}

里氏替换原则的用法

自己写两个类来包裹两个不同的UnityAction,然后让他们继承自同一接口,就可以实现里氏替换原则

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

public class EventCenterManager : SingletonPatternBase<EventCenterManager>
{
    //键表示命令的名字
    //值表示命令具体要执行的逻辑
    Dictionary<string, IEventInfo> eventsDictionary = new Dictionary<string, IEventInfo>();

    public void AddListener(object command,UnityAction call)
    {
        string key = command.GetType().Name + "_" + command.ToString();
        if (eventsDictionary.ContainsKey(key))
        {
            (eventsDictionary[key] as EventInfo).action += call;
        }
        else
            eventsDictionary.Add(key,new EventInfo(call));
    }

    //传递带参数的委托
    public void AddListener<T>(object command,UnityAction<T> call)
    {
        string key = command.GetType().Name + "_" + command.ToString() + "_" + typeof(T).Name;
        if (eventsDictionary.ContainsKey(key))
        {
            (eventsDictionary[key] as EventInfo<T>).action += call;
        }
        else
            eventsDictionary.Add(key, new EventInfo<T>(call));
    }

    /// <summary>
    /// 取消监听的命令
    /// </summary>
    public void RemoveListener(object command,UnityAction call)
    {
        string key = command.GetType().Name + "_" + command.ToString();
        if (eventsDictionary.ContainsKey(key))
        {
            (eventsDictionary[key] as EventInfo).action -= call;
        }
    }

    //取消带有参数的监听事件
    public void RemoveListener<T>(object command,UnityAction<T> call)
    {
        string key = command.GetType().Name + "_" + command.ToString() + "_" + typeof(T).Name;
        if (eventsDictionary.ContainsKey(key))
        {
            (eventsDictionary[key] as EventInfo<T>).action -= call;
        }
    }

    //移除一条命令所对应的全部委托
    public void RemoveListeners(object command)
    {
        string key = command.GetType().Name + "_" + command.ToString();
        if (eventsDictionary.ContainsKey(key))
        {
            (eventsDictionary[key] as EventInfo).action = null;
        }
    }

    //带有参数的移除一条命令中所有委托
    public void RemoveListeners<T>(object command)
    {
        string key = command.GetType().Name + "_" + command.ToString() + "_" + typeof(T).Name;
        if (eventsDictionary.ContainsKey(key))
        {
            (eventsDictionary[key] as EventInfo<T>).action = null;
        }
    }

    //发送命令
    public void DisPatch(object command)
    {
        string key = command.GetType().Name + "_" + command.ToString();
        if (eventsDictionary.ContainsKey(key))
        {
            (eventsDictionary[key] as EventInfo).action?.Invoke();
        }
    }

    //给带参数的事件写的重载
    public void DisPatch<T>(object command,T parameter)
    {
        string key = command.GetType().Name + "_" + command.ToString() + "_" + typeof(T).Name;
        if (eventsDictionary.ContainsKey(key))
        {
            (eventsDictionary[key] as EventInfo<T>).action?.Invoke(parameter);
        }
    }

    /// <summary>
    /// 移除所有带或者不带参数的监听事件,切换场景可以考虑使用
    /// </summary>
    public void RemoveAllListeners()
    {
        eventsDictionary.Clear();
    }

    private interface IEventInfo { }  //仅用于里氏替换原则

    private class EventInfo:IEventInfo
    {
        public UnityAction action;

        public EventInfo(UnityAction call)
        {
            action += call;
        }
    }

    private class EventInfo<T> :IEventInfo
    {
        public UnityAction<T> action;

        public EventInfo(UnityAction<T> call)
        {
            action += call;
        }
    }

}

传递多个参数的委托事件:文章来源地址https://www.toymoban.com/news/detail-649232.html

  • 可以写一个信息类来存储多个信息,然后事件中传递这个信息类。这样就还是一个参数
  • 或者额外写含有两个参数的方法,写含有三个的,四个的(可行,但是费劲)
  • 元组(但是我不知道这个是什么)

到了这里,关于Unity框架学习--5 事件中心管理器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [Unity] No.3 EventManager事件管理 与 观察者模式

    前文讲到了InputManager,在其后需要一个事件的管理者用于调度任务的执行,包括: ①查看发生了什么事; ②出事后看看都需要通知谁干什么事; 以上两个内容就对应了EventManager中关键的 监听 和 回调 ,而在讲EventManager之前还需要知道,它是符合观察者这一模式的。 此处不

    2024年02月08日
    浏览(30)
  • Unity实用框架(一)场景管理框架

    众所周知,Unity引擎本身提供了具有切换场景功能的SceneManager模块,但只包含比较基础的功能,比如简单的切换场景、创建场景等,想要使得我们的场景管理框架能够适用于更加复杂的情形,显然需要一套更加强大的接口。下面,笔者将提供一种撰写灵活好用的SceneManager的可

    2023年04月09日
    浏览(23)
  • Unity框架-Mono管理器

    一、前言 在Unity开发中,经常会遇到需要在没有继承 MonoBehaviour 的类中使用协程和Update的情况。为了解决这个问题,我们可以使用Mono管理器,该管理器允许非 MonoBehaviour 类使用一些常用的Mono方法。在本篇文章中,我们将深入探讨Mono管理器的实现以及如何使用它进行协程管理

    2024年01月20日
    浏览(29)
  • Unity 3D 开发--UI管理框架

    一、UI基类 一般情况下都是用Panel做容器来放各种控件的,一个Panle相当一个UI小界面,然后做成Prefab进行加载,所有界面都有载入载出功能,有的可能还有等待和恢复的,适合建立一个UI基类,然后各个子界面继承。 二、UI子类 每个UI子界面都继承基类,然后实现各个方法,

    2024年02月13日
    浏览(27)
  • 【Unity 框架】QFramework v1.0 使用指南 工具篇:05. ResKit 资源管理&开发解决方案 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏

    Res Kit,是资源管理快速开发解决方案 特性如下: 可以使用一个 API 从 dataPath、Resources、StreammingAssetPath、PersistentDataPath、网络等地方加载资源。 基于引用计数,简化资源加载和卸载。 拥抱游戏开发流程中的不同阶段 开发阶段不用打 AB 直接从 dataPath 加载。 测试阶段支持只需打

    2024年02月01日
    浏览(40)
  • 【Unity3D框架】Unity Package Manager自定义包管理实践

            在公司开发的前两个项目,虽然搭建了基础的框架,有一些目录划分,但是当项目复杂度增长到一定程度,以及后续新开了一些新的项目之后,对于基础框架的管理就遇到了一些挑战,主要体现在以下几个方面:         1、多项目之间拷贝了类似的基础框架,但是

    2024年02月03日
    浏览(60)
  • Unity动画系统学习笔记(二)根运动、动画事件与状态机行为

    在学习根运动前需要了解两个名词: 身体变换 :身体变换是角色的质心。它用于 Mecanim 的重定向引擎,并提供最稳定的移位模型。身体方向是相对于 Avatar T 形姿势的下身和上身方向的平均值。身体变换和方向存储在动画剪辑中(使用 Avatar 中设置的肌肉定义)。它们是动画

    2023年04月11日
    浏览(31)
  • Unity框架学习--2

    接上文 IOC 容器是一个很方便的模块管理工具。 除了可以用来注册和获取模块,IOC 容器一般还会有一个隐藏的功能,即: 抽象-实现 这种形式注册和获取对象的方式是符合 依赖倒置原则 的。 依赖倒置原则(Dependence Inversion Principle):程序要依赖于抽象接口,不要依赖于具体

    2024年02月13日
    浏览(23)
  • unity进阶学习笔记:消息框架

    1 使用消息框架的目的 对于小型游戏,可能不需要任何框架,而是让各个游戏脚本直接相互通信。如要实现玩家受到攻击血量减少,通过玩家控制类向血条脚本发送消息减少血量。但是这样直接通信会导致各脚本通信关系记为复杂,并且每一个脚本都和多个脚本有联系,导致

    2024年02月06日
    浏览(27)
  • Unity Xlua热更新框架(五):Lua和UI管理

    :::info Lua存在两种加载器,一种默认加载器(env.DoString(\\\"require(‘test’)\\\"直接用了默认加载其),直接调用StreamingAssets中的脚本);一种是自定义加载器(env.AddLoader(Envpath)),优先于默认加载器(下文DoString就是从自定义加载器的路径读取的),并且当Lua代码执行require函数时,

    2024年02月06日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包