Unity框架学习--4 Mono管理器

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

作用:使不继承MonoBehaviour的类能够开启协程,并且可以使用FixedUpdate、Update、LateUpdate进行每帧更新。

原理:
1、在场景中创建一个继承MonoBehaviour的“执行者”脚本,这个脚本就专门用来开启协程和监听帧更新。
2、Mono管理器访问这个“执行者”脚本,就可以实现所需的效果。

创建一个空物体,挂载一个继承自MonoBehaviour 的脚本(没有任何方法也可以)

没有继承的那个脚本代码这样写:

public void Show()
    {
        GameObject go = GameObject.Find("MonoController");
        go.AddComponent<MonoController>().StartCoroutine(MyCoroutine());
    }

    IEnumerator MyCoroutine()
    {
        while (true)
        {
            Debug.Log("协程执行中");
            yield return null;
        }
    }

就可以调用了

Mono管理器开启协程

public class MonoController : MonoBehaviour
{
    
}

MonoManager 管理类,自动创建场景物体并挂载继承有Mono的脚本

继承SingletonPatternBase 作为一个 单例存在

public class MonoManager : SingletonPatternBase<MonoManager>
{
    private MonoManager() { }

    private MonoController monoController;

    public MonoController MonoController
    {
        get
        {
            if (monoController == null)
            {
                GameObject go = new GameObject(typeof(MonoController).Name);
                monoController = go.AddComponent<MonoController>();
            }
            return monoController;
            
        }
    }

    //一个专门让外部用来开启协程的方法
    public Coroutine StartCoroutine(IEnumerator routine)
    {
        return MonoController.StartCoroutine(routine);
    }

Mono管理器停止协程

//停止协程的方法
    public void StopCoroutine(IEnumerator routine)
    {
        MonoController.StopCoroutine(routine);
    }

    //停止协程的方法 重载
    public void StopCoroutine(Coroutine coroutine)
    {
        MonoController.StopCoroutine(coroutine);
    }

    //停止所有协程的方法
    public void StopAllCoroutine()
    {
        MonoController.StopAllCoroutines();
    }
public class Player
{
    Coroutine coroutine;

    public void Show()
    {
        coroutine = MonoManager.Instance.StartCoroutine(MyCoroutine());
    }

    public void Hide()
    {
        MonoManager.Instance.StopCoroutine(coroutine);
    }

    public void HideAll()
    {
        MonoManager.Instance.StopAllCoroutine();
    }

在具体的脚本里直接MonoManager.Instance.xxx方法就可以执行

注意停止协程的写法!!!

Mono管理器Update事件监听

利用委托事件,传递方法进去执行

执行者脚本

/// <summary>
/// 执行者脚本。其他脚本可以通过它来开启停止协程,也可以通过它来监听Update,FixedUpdate。LateUpdate
/// </summary>
public class MonoController : MonoBehaviour
{
    //在生命周期方法中执行的时间
    event UnityAction updateEvent;

    private void Update()
    {
        updateEvent?.Invoke();
    }

    public void AddUpdateListener(UnityAction call)
    {
        updateEvent += call;
    }

    public void RemoveUpdateListener(UnityAction call)
    {
        updateEvent -= call;
    }

    public void RemoveAllUPdateListeners()
    {
        updateEvent = null;
    }

管理者脚本

//添加Update事件
    public void AddUpdateListener(UnityAction call)
    {
        monoController.AddUpdateListener(call);
    }

    //移除Update事件
    public void RemoveUpdateListener(UnityAction call)
    {
        monoController.RemoveUpdateListener(call);
    }

    //移除所有Update事件
    public void RemoveAllUPdateListeners()
    {
        monoController.RemoveAllUPdateListeners();
    }

具体的需要执行的方法的脚本传递委托脚本

public void PrintUpdate()
    {   //添加可以添加Lambda 表达式,但是无法从委托列表中删掉这个Lambda表达式  
        //所以一般不是很简单的逻辑不建议使用lambda表达式
        //可以声明为一个专门的方法然后添加进去
        //lambd 表达式
        MonoManager.Instance.AddUpdateListener(() => 
        { 
            Debug.Log("Update"); 
        });
    }

    public void StopPrintUpdate()
    {                               
        //这个方法是无效的,无法成功删除
        //lambd 表达式
        MonoManager.Instance.RemoveUpdateListener(() =>
        {
            Debug.Log("Update");
        });
    }

    public void StopAllPrintUpdate()
    {
        MonoManager.Instance.RemoveAllUPdateListeners();
    }

Mono管理器优化:嵌套类

很简单,就是把MonoController 声明到 MonoManager 中,没干什么额外的工作文章来源地址https://www.toymoban.com/news/detail-649470.html

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

public class MonoManager : SingletonPatternBase<MonoManager>
{
    private MonoManager() { }

    private MonoController monoExecuter;

    public MonoController MonoExecuter
    {
        get
        {
            if (monoExecuter == null)
            {
                GameObject go = new GameObject(typeof(MonoController).Name);
                monoExecuter = go.AddComponent<MonoController>();
            }
            return monoExecuter;
            
        }
    }

    //一个专门让外部用来开启协程的方法
    public Coroutine StartCoroutine(IEnumerator routine)
    {
        return MonoExecuter.StartCoroutine(routine);
    }

    //停止协程的方法
    public void StopCoroutine(IEnumerator routine)
    {
        if (routine != null)
        {
            MonoExecuter.StopCoroutine(routine);
        }
    }

    //停止协程的方法 重载
    public void StopCoroutine(Coroutine coroutine)
    {
        if (coroutine != null)
        {
            MonoExecuter.StopCoroutine(coroutine);
        }
    }

    //停止所有协程的方法
    public void StopAllCoroutine()
    {
        MonoExecuter.StopAllCoroutines();
    }

    //添加Update事件
    public void AddUpdateListener(UnityAction call)
    {
        monoExecuter.AddUpdateListener(call);
    }

    //移除Update事件
    public void RemoveUpdateListener(UnityAction call)
    {
        monoExecuter.RemoveUpdateListener(call);
    }

    //移除所有Update事件
    public void RemoveAllUPdateListeners()
    {
        monoExecuter.RemoveAllUPdateListeners();
    }

    /// <summary>
    /// 执行者脚本。其他脚本可以通过它来开启停止协程,也可以通过它来监听Update,FixedUpdate。LateUpdate
    /// </summary>
    public class MonoController : MonoBehaviour
    {
        //在生命周期方法Update中执行的事件
        event UnityAction updateEvent;

        //在生命周期方法FixUpdate中执行的事件
        event UnityAction fixUpdateEvent;

        private void FixedUpdate()
        {
            fixUpdateEvent?.Invoke();
        }

        private void Update()
        {
            updateEvent?.Invoke();
        }

        public void AddUpdateListener(UnityAction call)
        {
            updateEvent += call;
        }

        public void RemoveUpdateListener(UnityAction call)
        {
            if (updateEvent != null)
            {
                updateEvent -= call;
            }
        }

        public void RemoveAllUPdateListeners()
        {
            updateEvent = null;
        }

        public void AddFixUpdateListener(UnityAction call)
        {
            fixUpdateEvent += call;
        }

        public void RemoveFixUpdateListener(UnityAction call)
        {
            if (fixUpdateEvent != null)
            {
                fixUpdateEvent -= call;

            }
        }

        public void RemoveAllFixUpdateListeners()
        {
            fixUpdateEvent = null;
        }
    }

}

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

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

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

相关文章

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

    作用 :访问其它脚本时,不直接访问,而是通过发送一条“命令”,让监听了这条“命令”的脚本自动执行对应的逻辑。 原理: 1、让脚本向事件中心添加事件,监听对应的“命令”。 2、发送“命令”,事件中心就会通知监听了这条“命令”的脚本,让它们自动执行对应的

    2024年02月13日
    浏览(24)
  • Unity—Mono.Data.Sqlite

    一、常用属性 Depth :获取一个值,用于指示当前行的嵌套深度 FieldCount :获取当前行中的列数 HasRows :获取一个值,该值指示SQLDataReader是否有行 IsClosed :指定的SQLDataReader实例是否已关闭 Item[Int32] :获取指定列(数字索引),通常在While.Read()中使用 Item[String] :获取指定列(字

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

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

    2023年04月09日
    浏览(23)
  • 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)
  • 2023年Unity Il2CPP/MONO FPS逆向工程

    实战引擎 : Unity Il2CPP/Mono 学完可做 : 森林之子,后室,逃离塔科夫,BattleBit,Rust等 几乎通杀全部Unity引擎游戏 简介: 实战编程代码:C/C++ B站空间:https://space.bilibili.com/2134677790 课程详细目录 :2023年Unity Il2CPP/MONO FPS逆向工程 · 语雀 联系方式 :点击课程详细目录查看 效果图

    2024年02月13日
    浏览(29)
  • Unity框架学习--2

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

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

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

    2024年02月06日
    浏览(27)
  • Mac vscode unity mono无法正常加载,c#代码不能正常补全的解决方法

    初学unity,用Mac vscode来开发,遇见了不能正常补全代码的问题。能补全代码但是补全的不是unity的代码。 终于解决了。 首先最新版的net.sdk 和 Mono (Stable channel)一定安装好 https://www.mono-project.com/download/stable/ https://learn.microsoft.com/ja-jp/dotnet/core/install/macos vscode里边该有的扩展插件

    2024年02月02日
    浏览(32)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包