社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
我的需求,主要是,协程结束事件的获取。我需要在一个协程结束的时候做一些事情,这时候需要自己做一些封装。
找到了两篇文章,第一篇写的比较复杂,但是作者是个大佬:https://blog.csdn.net/u013709166/article/details/53751090。
第二篇抄了一遍,还是比较好理解的。就打算用第二篇这种方式了:https://www.cnblogs.com/123ing/p/3704967.html
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// 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.
/// 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.Invoke(manual);
}
TaskManager.TaskState task;
}
public 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.Invoke(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);
}
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();
}
bool rtt = true;
void StopRotate(bool finish)
{
rtt = !finish;
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.S))
{
Task spam = new Task(MyAwesomeTask());
spam.Finished += StopRotate;
new Task(TaskKiller(5, spam));
}
if (rtt)
{
transform.RotateAround(transform.position, transform.up, 30 * Time.deltaTime);
}
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!