zoukankan      html  css  js  c++  java
  • 封装你的协程Unity TaskManager

    unity5提供了协程,不过用起来很蛋疼,当然如果是unity2017 你就可以用async await了

    提供一个TaskManager来封装协程(github  https://github.com/krockot/Unity-TaskManager)

    1.TaskManager

    /// TaskManager.cs
    /// Copyright (c) 2011, Ken Rockot  <k-e-n-@-REMOVE-CAPS-AND-HYPHENS-oz.gs>.  All rights reserved.
    /// Everyone is granted non-exclusive license to do anything at all with this code.
    ///
    /// This is a new coroutine interface for Unity.
    ///
    /// The motivation for this is twofold:
    ///
    /// 1. The existing coroutine API provides no means of stopping specific
    ///    coroutines; StopCoroutine only takes a string argument, and it stops
    ///    all coroutines started with that same string; there is no way to stop
    ///    coroutines which were started directly from an enumerator.  This is
    ///    not robust enough and is also probably pretty inefficient.
    ///
    /// 2. StartCoroutine and friends are MonoBehaviour methods.  This means
    ///    that in order to start a coroutine, a user typically must have some
    ///    component reference handy.  There are legitimate cases where such a
    ///    constraint is inconvenient.  This implementation hides that
    ///    constraint from the user.
    ///
    /// Example usage:
    ///
    /// ----------------------------------------------------------------------------
    /// IEnumerator MyAwesomeTask()
    /// {
    ///     while(true) {
    ///         Debug.Log("Logcat iz in ur consolez, spammin u wif messagez.");
    ///         yield return null;
    ////    }
    /// }
    ///
    /// IEnumerator TaskKiller(float delay, Task t)
    /// {
    ///     yield return new WaitForSeconds(delay);
    ///     t.Stop();
    /// }
    ///
    /// void SomeCodeThatCouldBeAnywhereInTheUniverse()
    /// {
    ///     Task spam = new Task(MyAwesomeTask());
    ///     new Task(TaskKiller(5, spam));
    /// }
    /// ----------------------------------------------------------------------------
    ///
    /// When SomeCodeThatCouldBeAnywhereInTheUniverse is called, the debug console
    /// will be spammed with annoying messages for 5 seconds.
    ///
    /// Simple, really.  There is no need to initialize or even refer to TaskManager.
    /// When the first Task is created in an application, a "TaskManager" GameObject
    /// will automatically be added to the scene root with the TaskManager component
    /// attached.  This component will be responsible for dispatching all coroutines
    /// behind the scenes.
    ///
    /// Task also provides an event that is triggered when the coroutine exits.
    
    using UnityEngine;
    using System.Collections;
    
    /// A Task object represents a coroutine.  Tasks can be started, paused, and stopped.
    /// It is an error to attempt to start a task that has been stopped or which has
    /// naturally terminated.
    public class Task
    {
        /// Returns true if and only if the coroutine is running.  Paused tasks
        /// are considered to be running.
        public bool Running
        {
            get
            {
                return task.Running;
            }
        }
    
        /// Returns true if and only if the coroutine is currently paused.
        public bool Paused
        {
            get
            {
                return task.Paused;
            }
        }
    
        /// Delegate for termination subscribers.  manual is true if and only if
        /// the coroutine was stopped with an explicit call to Stop().
        public delegate void FinishedHandler(bool manual);
    
        /// Termination event.  Triggered when the coroutine completes execution.
        public event FinishedHandler Finished;
    
        /// Creates a new Task object for the given coroutine.
        ///
        /// If autoStart is true (default) the task is automatically started
        /// upon construction.
        public Task(IEnumerator c, bool autoStart = true)
        {
            task = TaskManager.CreateTask(c);
            task.Finished += TaskFinished;
            if (autoStart)
                Start();
        }
    
        /// Begins execution of the coroutine
        public void Start()
        {
            task.Start();
        }
    
        /// Discontinues execution of the coroutine at its next yield.
        public void Stop()
        {
            task.Stop();
        }
    
        public void Pause()
        {
            task.Pause();
        }
    
        public void Unpause()
        {
            task.Unpause();
        }
    
        void TaskFinished(bool manual)
        {
            FinishedHandler handler = Finished;
            if (handler != null)
                handler(manual);
        }
    
        TaskManager.TaskState task;
    }
    
    class TaskManager : MonoBehaviour
    {
        public class TaskState
        {
            public bool Running
            {
                get
                {
                    return running;
                }
            }
    
            public bool Paused
            {
                get
                {
                    return paused;
                }
            }
    
            public delegate void FinishedHandler(bool manual);
            public event FinishedHandler Finished;
    
            IEnumerator coroutine;
            bool running;
            bool paused;
            bool stopped;
    
            public TaskState(IEnumerator c)
            {
                coroutine = c;
            }
    
            public void Pause()
            {
                paused = true;
            }
    
            public void Unpause()
            {
                paused = false;
            }
    
            public void Start()
            {
                running = true;
                singleton.StartCoroutine(CallWrapper());
            }
    
            public void Stop()
            {
                stopped = true;
                running = false;
            }
    
            IEnumerator CallWrapper()
            {
                yield return null;
                IEnumerator e = coroutine;
                while (running)
                {
                    if (paused)
                        yield return null;
                    else
                    {
                        if (e != null && e.MoveNext())
                        {
                            yield return e.Current;
                        }
                        else
                        {
                            running = false;
                        }
                    }
                }
    
                FinishedHandler handler = Finished;
                if (handler != null)
                    handler(stopped);
            }
        }
    
        static TaskManager singleton;
    
        public static TaskState CreateTask(IEnumerator coroutine)
        {
            if (singleton == null)
            {
                GameObject go = new GameObject("TaskManager");
                singleton = go.AddComponent<TaskManager>();
            }
            return new TaskState(coroutine);
        }
    }

    2.使用说明

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Test : MonoBehaviour {
    
        // Use this for initialization
        void Start () {
            TaskManager.TaskState task = TaskManager.CreateTask(MyC());
            //然后单独操作这个task就行了,很方便
            task.Start();//任务开始
            task.Finished += Task_Finished;//完成回调
            task.Stop();//任务停止
            task.Pause();//任务暂停
            task.Unpause();//任务恢复
        }
    
        private void Task_Finished(bool manual)
        {
            Debug.Log("任务完成");
        }
    
        IEnumerator MyC()
        {
            yield return new WaitForSeconds(1);
            Debug.Log("hahahhhh");
        }
    
    }
  • 相关阅读:
    (转载)你好,C++(25)函数调用和它背后的故事5.1.2 函数调用机制
    (转载)你好,C++(24)好大一个箱子!5.1.1 函数的声明和定义
    (转载)你好,C++(23) 4.4.2 工资程序成长记:用数组处理批量数据,用循环结构执行重复动作
    (转载)你好,C++(22) 排排坐,吃果果——4.3.3 for循环:某个范围内…每个都…
    【NOI2002T4】荒岛野人-扩展欧几里得
    【POJ1743】Musical Theme-后缀数组+二分答案
    【POJ1743】Musical Theme-后缀数组+二分答案
    【NOI2014T1】起床困难综合症-贪心+位运算
    【NOI2014T1】起床困难综合症-贪心+位运算
    【APIO2012T1】派遣-贪心+左偏树
  • 原文地址:https://www.cnblogs.com/sanyejun/p/8743754.html
Copyright © 2011-2022 走看看