Last active
July 10, 2020 04:38
-
-
Save qwe321qwe321qwe321/958c405524dbad0a12aa06589936d52e to your computer and use it in GitHub Desktop.
BetterCoroutine is a wrapper of UnityEngine.Coroutine to make it safe and convenience. It provides a better approach to access and maintain the coroutine status and lifecycle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* BetterCoroutine is a wrapper of UnityEngine.Coroutine. | |
* It provides a better approach to access and maintain the coroutine status and lifecycle. | |
* Created by PeDev 2020 https://gist.github.com/qwe321qwe321qwe321/958c405524dbad0a12aa06589936d52e | |
*/ | |
using System.Collections; | |
using UnityEngine; | |
namespace Pedev { | |
/// <summary> | |
/// The Coroutine wrapper provides a better approach to maintain the coroutine status and lifecycle. | |
/// </summary> | |
public class BetterCoroutine { | |
private Coroutine m_Coroutine; | |
private MonoBehaviour m_MonoProxy; | |
/// <summary> | |
/// Is the coroutine running? | |
/// </summary> | |
public bool IsRunning { get => m_Coroutine != null; } | |
/// <summary> | |
/// Create a new BetterCoroutine with the specific MonoBehaviour proxy and run the specific routine. | |
/// </summary> | |
/// <param name="monoProxy">The MonoBehaviour as a proxy for running coroutine.</param> | |
public static BetterCoroutine StartCoroutine(MonoBehaviour monoProxy, IEnumerator routine) { | |
BetterCoroutine coroutine = new BetterCoroutine(monoProxy); | |
coroutine.StartCoroutine(routine); | |
return coroutine; | |
} | |
/// <summary> | |
/// The Coroutine wrapper provides a better approach to maintain the coroutine status and lifecycle. | |
/// </summary> | |
/// <param name="monoProxy">The MonoBehaviour as a proxy for running coroutine.</param> | |
public BetterCoroutine(MonoBehaviour monoProxy) { | |
m_MonoProxy = monoProxy; | |
} | |
/// <summary> | |
/// Start a coroutine. | |
/// </summary> | |
/// <param name="routine"></param> | |
public void StartCoroutine(IEnumerator routine) { | |
if (!ValidateMono()) { return; } | |
StopCoroutine(); | |
m_Coroutine = m_MonoProxy.StartCoroutine(RoutineWrapper(routine)); | |
} | |
/// <summary> | |
/// Stop the running coroutine. | |
/// </summary> | |
public void StopCoroutine() { | |
if (!ValidateMono()) { return; } | |
if (m_Coroutine != null) { | |
m_MonoProxy.StopCoroutine(m_Coroutine); | |
m_Coroutine = null; | |
} | |
} | |
/// <summary> | |
/// Wrap the routine to set callbacks. | |
/// </summary> | |
/// <param name="routine"></param> | |
/// <returns></returns> | |
private IEnumerator RoutineWrapper(IEnumerator routine) { | |
yield return routine; | |
m_Coroutine = null; | |
} | |
/// <summary> | |
/// Validate the mono proxy is still alive. | |
/// </summary> | |
/// <returns></returns> | |
private bool ValidateMono() { | |
return m_MonoProxy != null; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using UnityEngine; | |
namespace Pedev { | |
/// <summary> | |
/// A simple example to moving this gameObject in the specific duration by BetterCoroutine. | |
/// </summary> | |
public class BetterCoroutineExample : MonoBehaviour { | |
public Vector3 movement = new Vector3(5f, 0, 0); | |
public float moveDuration = 3f; | |
private BetterCoroutine m_Coroutine; | |
// Initialize my components. | |
void Awake() { | |
m_Coroutine = new BetterCoroutine(this); | |
} | |
// Initialize my connections to others. | |
void OnGUI() { | |
if (GUI.Button(new Rect(10, 10, 300, 100), $"Move {movement} in {moveDuration} seconds")) { | |
// You can call it whenever you want. It will stop the first one immediately and restart it again. | |
// Therefore, you don't need to be worried about the coroutine safety. | |
m_Coroutine.StartCoroutine(Move(this.transform.position + movement, moveDuration)); | |
} | |
// And you can check if the coroutine is running without declaring any variables. | |
GUI.Label(new Rect(10, 110, 300, 100), m_Coroutine.IsRunning ? "Coroutine is running." : "Coroutine stop."); | |
} | |
IEnumerator Move(Vector3 targetPosition, float duration) { | |
Vector3 src = transform.position; | |
float time = 0f; | |
while(time < duration) { | |
transform.position = Vector3.Lerp(src, targetPosition, time / duration); | |
time += Time.deltaTime; | |
yield return null; | |
} | |
transform.position = targetPosition; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment