首页 > 其他分享 >Unity游戏框架设计之协程管理器

Unity游戏框架设计之协程管理器

时间:2024-04-29 21:33:45浏览次数:23  
标签:CoroutineTask 之协程 协程 coroutine Unity 管理器 null public finishHandler

Unity游戏框架设计之协程管理器

代码设计

/*
 * 协程管理器
 */
public class CoroutineManager : SingletonMono<CoroutineManager>
{
    /**
     * 创建 CoroutineTask
     */
    public CoroutineTask CreateCoroutine(IEnumerator coroutine, Action<bool> finishHandler = null, bool autoStart = true)
    {
        CoroutineTask coroutineTask = new CoroutineTask(coroutine, finishHandler);
        if (autoStart)
        {
            coroutineTask.Start();
        }
        return coroutineTask;
    }

    /**
     * 拓展一个协程
     */
    public IEnumerator ExtendCoroutine(IEnumerator coroutine, Action callback)
    {
        yield return coroutine;
        callback();
    }

    /**
     * 拥有生命周期的协程
     */
    public class CoroutineTask
    {
        private readonly IEnumerator _coroutine; // 协程
        private bool _running; // 是否执行中
        private bool _paused; // 是否已暂停
        private bool _stopped; // 是否已停止

        // 协程执行完成的回调函数。无论是协程执行完毕,还是协程被执行 Stop() 而终止,都执行此方法。
        // 参数为 true 当前仅当手动执行 Stop() 函数使得协程被终止。
        private readonly Action<bool> _finishHandler;
        private CoroutineTask _next; // 当前 CoroutineTask 执行完毕后,继续执行的下一个的 CoroutineTask。解决地狱回调问题。

        public CoroutineTask(IEnumerator coroutine, Action<bool> finishHandler = null)
        {
            _coroutine = coroutine;
            _running = _paused = _stopped = false;
            _finishHandler = finishHandler;
        }

        public CoroutineTask Next(IEnumerator coroutine, Action<bool> finishHandler = null)
        {
            _next = new CoroutineTask(coroutine, finishHandler);
            return _next;
        }

        public void Start()
        {
            _running = true;
            CoroutineManager.Instance.StartCoroutine(StarTask());
        }

        public void Pause()
        {
            _paused = true;
        }

        public void Unpause()
        {
            _paused = false;
        }

        public void Stop()
        {
            _stopped = true;
            _running = false;
        }

        private IEnumerator StarTask()
        {
            // yield return null;
            while (_running)
            {
                if (_paused)
                {
                    yield return null;
                }
                else
                {
                    if (_coroutine != null && _coroutine.MoveNext())
                    {
                        yield return _coroutine.Current;
                    }
                    else
                    {
                        _running = false;
                    }
                }
            }
            if (_finishHandler != null)
            {
                _finishHandler(_stopped);
            }
            if (_next != null)
            {
                _next.Start();
            }
        }
    }
}

代码说明

代码参考 Github 上 krockot/Unity-TaskManager 的 TaskManager.cs 实现。

(一)所有协程统一在一个对象上执行。防止协程执行过程中,由于游戏对象被禁用,导致协程中断执行的问题。

(二)对协程进行生命周期控制,允许对协程执行开始,暂停与终止操作。

(三)允许配置协程执行完毕时的回调函数

(四)解决协程的地狱回调问题

后记

由于个人能力有限,文中不免存在疏漏,恳求大家斧正,一起交流,共同进步。

标签:CoroutineTask,之协程,协程,coroutine,Unity,管理器,null,public,finishHandler
From: https://www.cnblogs.com/kkelin/p/18166680

相关文章

  • Unity游戏框架设计之单例Mono
    Unity游戏框架设计之单例Mono简单介绍在编写Unity脚本的过程中,我们通常需要编写一些依赖于MonBehaviour生命周期且全局始终唯一的类,比如EventManager、TaskManager、ResourceManager和UIManager等等。我们可以基于单例模式,设计出名为SingletonMono的单例类,然后让拥......
  • Linux软件包管理器,RPM和YUM的区别
    RPMRPM(RedhatLinuxPacketManger)是RedHat公司随RedhatLinux推出的一个软件包管理器,通过它能够轻松实现Linux软件的安装。但是,需要手动解决软件包的依赖关系。YUMYUM(YellowdogUpdater,Modified)是一个Shell前端软件包管理器。基于RPM包管理器,能够从指定的服务器自动......
  • unity C# 每隔一段时间执行一次
    在Unity中使用C#编写脚本可以通过定时器来实现每隔一段时间执行一次的功能。下面是一种常见的实现方式:usingUnityEngine;publicclassTimerExample:MonoBehaviour{privatefloatinterval=2f;//设置时间间隔为2秒voidStart(){InvokeRepeating("Ex......
  • 更新!!!Unity移动端游戏性能优化简谱
    UWA官方出品,结合多年优化经验撰写了《Unity移动端游戏性能优化简谱》,文章从Unity移动端游戏优化的一些基础讨论出发,例举和分析了近几年基于Unity开发的移动端游戏项目中最为常见的部分性能问题,并展示了如何使用UWA的性能检测工具确定和解决这些问题。 (1)性能优化的基本逻辑......
  • Unity性能优化——字符串和文本
    字符串和文本字符串和文本的处理不当是Unity项目中性能问题的常见原因。在C#中,所有字符串均不可变。对字符串的任何操作均会导致分配一个完整的新字符串。这种操作的代价相对比较高,而且在大型字符串上、大型数据集上或紧凑循环中执行时,接连不断的重复的字符串可能发展成性能......
  • Navicat连接SQL server出现:[IM002] [Microsoft][ODBC 驱动程序管理器] 未发现数据源名
    问题 解决方法一找到Navicat的安装路径,然后找到sqlncli_x64.msi文件并安装,安装成功后重启Navicat重新进行连接,看是否成功。 解决方法二如果方法一没有找到找到sqlncli_x64.msi还是Navicat的安装路径,然后找到msodbcsql_64.msi文件并安装,安装成功后重启Navicat重新进行连接......
  • Unity的AOP应用 应用场景 C#
    在C#中,Unity容器是一个功能强大的依赖注入(DI)容器,它提供了丰富的配置选项来管理对象的生命周期,支持特殊类型的处理,并允许通过配置文件来简化注册和配置过程。同时,Unity还提供了面向切面编程(AOP)的功能,允许开发者在不改变现有代码逻辑的情况下,为对象的方法添加额外的行为。1.Unity......
  • Windows编程系列:设置资源管理器背景
    偶然的机会,在github上发现了一个有趣且优秀的项目,https://github.com/Maplespe/explorerTool。这里学习了一下,并顺带学习了一下涉及的相关知识点。不得不感叹作者的厉害之处,能想到这种方法。 主要实现原理是:1、通过ApiHook,在调用CreateWindows函数创建窗口时,如果是资源管理器......
  • Unity3D 打造基于AStar的寻路与导航详解
    Unity3D打造基于AStar的寻路与导航详解BYCW丶零夜 ​关注 2人赞同了该文章前言寻路与导航是游戏开发中非常重要的一部分,它可以让游戏中的角色自动寻找到目标位置,并避开障碍物。本文将介绍如何使用Unity3D打造基于AStar算法的寻路与导航解,包括技术详......
  • Unity获取指定文件夹下的所有文件
    usingSystem.IO;publicvoidGetFiles(){stringpath=string.Format("{0}",Application.streamingAssetsPath);//stringpath=string.Format("{0}",@"C:\Users\USER\Desktop\JXBWG\Assets\StreamingAssets&qu......