using UnityEngine; using System; using System.Collections; public static class MonoBehaviourExtensions { public static void SafeStopCoroutine(this MonoBehaviour monoBehaviour, Coroutine c){ if(c != null) monoBehaviour.StopCoroutine(c); } /// 1フレーム待機してからActionデリゲートを呼び出す public static Coroutine CallWaitForOneFrame(this MonoBehaviour monoBehaviour, Action act){ return monoBehaviour.StartCoroutine(DoCallWaitForOneFrame(act)); } private static IEnumerator DoCallWaitForOneFrame(Action act){ yield return null; act(); } /// 指定フレーム数待機してからActionデリゲートを呼び出す public static Coroutine CallWaitForFrame(this MonoBehaviour monoBehaviour, int frameCount, Action act){ return monoBehaviour.StartCoroutine(DoCallWaitForFrame(frameCount, act)); } private static IEnumerator DoCallWaitForFrame(int frameCount, Action act){ for(int i = 0; i < frameCount; ++i) yield return null; act(); } /// 1FixedUpdate待機してからActionデリゲートを呼び出す public static Coroutine CallWaitForOneFixedUpdate(this MonoBehaviour monoBehaviour, Action act){ return monoBehaviour.StartCoroutine(DoCallWaitForOneFixedUpdate(act)); } private static IEnumerator DoCallWaitForOneFixedUpdate(Action act){ yield return new WaitForFixedUpdate(); act(); } /// 指定FixedUpdate数待機してからActionデリゲートを呼び出す public static Coroutine CallWaitForFixedUpdate(this MonoBehaviour monoBehaviour, int frameCount, Action act){ return monoBehaviour.StartCoroutine(DoCallWaitForFixedUpdate(frameCount, act)); } private static IEnumerator DoCallWaitForFixedUpdate(int frameCount, Action act){ for(int i = 0; i < frameCount; ++i) yield return new WaitForFixedUpdate(); act(); } /// 指定秒数待機してからActionデリゲートを呼び出す public static Coroutine CallWaitForSeconds(this MonoBehaviour monoBehaviour, float seconds, Action act){ return monoBehaviour.StartCoroutine(DoCallWaitForSeconds(seconds, act)); } private static IEnumerator DoCallWaitForSeconds(float seconds, Action act){ yield return new WaitForSeconds(seconds); act(); } public static Coroutine CallWaitForSeconds(this MonoBehaviour monoBehaviour, float seconds, Action act, Action callback){ return monoBehaviour.StartCoroutine(DoCallWaitForSeconds(seconds, act, callback)); } private static IEnumerator DoCallWaitForSeconds(float seconds, Action act, Action callback){ float t = 0.0f; act(t); do{ yield return null; t += Time.deltaTime; act(t); }while(t < seconds); callback(); } public static Coroutine CallWaitForRealTimeSeconds(this MonoBehaviour monoBehaviour, float seconds, Action callback){ return monoBehaviour.StartCoroutine(DoCallWaitForRealTimeSeconds(seconds, ActionExtensions.EmptyActionFloat, callback)); } public static Coroutine CallWaitForRealTimeSeconds(this MonoBehaviour monoBehaviour, float seconds, Action act, Action callback){ return monoBehaviour.StartCoroutine(DoCallWaitForRealTimeSeconds(seconds, act, callback)); } private static IEnumerator DoCallWaitForRealTimeSeconds(float seconds, Action act, Action callback){ float startupTime = Time.realtimeSinceStartup; float t = 0.0f; act(t); while(true){ yield return null; t = (Time.realtimeSinceStartup - startupTime); if(t >= seconds){ act(seconds); break; }else{ act(t); } } callback(); } public static Coroutine CallLerp(this MonoBehaviour monoBehaviour, float duration, Action act){ return monoBehaviour.CallLerp(duration, act, ActionExtensions.EmptyAction); } public static Coroutine CallLerp(this MonoBehaviour monoBehaviour, float duration, Action act, Action callback){ return monoBehaviour.StartCoroutine(DoCallLerp(duration, act, callback)); } public static IEnumerator DoCallLerp(float duration, Action act){ return DoCallLerp(duration, act, ActionExtensions.EmptyAction); } public static IEnumerator DoCallLerp(float duration, Action act, Action callback){ float t = 0.0f; act(t); while(true){ yield return null; t += Time.deltaTime / duration; if(t >= 1.0f){ act(1.0f); break; }else{ act(t); } } callback(); } public static Coroutine CallFixedLerp(this MonoBehaviour monoBehaviour, float duration, Action act){ return monoBehaviour.CallFixedLerp(duration, act, ActionExtensions.EmptyAction); } public static Coroutine CallFixedLerp(this MonoBehaviour monoBehaviour, float duration, Action act, Action callback){ return monoBehaviour.StartCoroutine(DoCallFixedLerp(duration, act, callback)); } public static IEnumerator DoCallFixedLerp(float duration, Action act){ return DoCallFixedLerp(duration, act, ActionExtensions.EmptyAction); } public static IEnumerator DoCallFixedLerp(float duration, Action act, Action callback){ float t = 0.0f; act(t); while(true){ yield return new WaitForFixedUpdate(); t += Time.fixedDeltaTime / duration; if(t >= 1.0f){ act(1.0f); break; }else{ act(t); } } callback(); } public static Coroutine CallFixedLerpRealTime(this MonoBehaviour monoBehaviour, float duration, Action act){ return monoBehaviour.CallFixedLerpRealTime(duration, act, ActionExtensions.EmptyAction); } public static Coroutine CallFixedLerpRealTime(this MonoBehaviour monoBehaviour, float duration, Action act, Action callback){ return monoBehaviour.StartCoroutine(DoCallFixedLerpRealTime(duration, act, callback)); } public static IEnumerator DoCallFixedLerpRealTime(float duration, Action act){ return DoCallFixedLerpRealTime(duration, act, ActionExtensions.EmptyAction); } public static IEnumerator DoCallFixedLerpRealTime(float duration, Action act, Action callback){ float t = 0.0f; act(t); while(true){ yield return new WaitForFixedUpdate(); t += Time.fixedUnscaledDeltaTime / duration; if(t >= 1.0f){ act(1.0f); break; }else{ act(t); } } callback(); } public static Coroutine CallLerpSmooth(this MonoBehaviour monoBehaviour, float duration, Action act){ return monoBehaviour.CallLerpSmooth(duration, act, ActionExtensions.EmptyAction); } public static Coroutine CallLerpSmooth(this MonoBehaviour monoBehaviour, float duration, Action act, Action callback){ return monoBehaviour.StartCoroutine(DoCallLerpSmooth(duration, act, callback)); } public static IEnumerator DoCallLerpSmooth(float duration, Action act){ return DoCallLerpSmooth(duration, act, ActionExtensions.EmptyAction); } public static IEnumerator DoCallLerpSmooth(float duration, Action act, Action callback){ float t = 0.0f; act(t); while(true){ yield return null; t += Time.smoothDeltaTime / duration; if(t >= 1.0f){ act(1.0f); break; }else{ act(t); } } callback(); } public static Coroutine CallLerpRealtime(this MonoBehaviour monoBehaviour, float duration, Action act){ return monoBehaviour.CallLerpRealtime(duration, act, ActionExtensions.EmptyAction); } public static Coroutine CallLerpRealtime(this MonoBehaviour monoBehaviour, float duration, Action act, Action callback){ return monoBehaviour.StartCoroutine(DoCallLerpRealtime(duration, act, callback)); } public static IEnumerator DoCallLerpRealtime(float duration, Action act){ return DoCallLerpRealtime(duration, act, ActionExtensions.EmptyAction); } public static IEnumerator DoCallLerpRealtime(float duration, Action act, Action callback){ float startupTime = Time.realtimeSinceStartup; float t = 0.0f; act(t); while(true){ yield return null; t = (Time.realtimeSinceStartup - startupTime); if(t >= duration){ act(1.0f); break; }else{ act(t / duration); } } callback(); } /// 指定秒間、指定秒間隔でactionを行う public static Coroutine CallTimer(this MonoBehaviour monoBehaviour, float seconds, float interval, Action action){ return monoBehaviour.CallTimer(seconds, 0.0f, interval, action, ActionExtensions.EmptyAction); } public static Coroutine CallTimer(this MonoBehaviour monoBehaviour, float seconds, float interval, Action action, Action callback){ return monoBehaviour.StartCoroutine(DoCallTimer(seconds, 0.0f, interval, action, callback)); } public static Coroutine CallTimer(this MonoBehaviour monoBehaviour, float seconds, float firstTime, float interval, Action action){ return monoBehaviour.CallTimer(seconds, firstTime, interval, action, ActionExtensions.EmptyAction); } public static Coroutine CallTimer(this MonoBehaviour monoBehaviour, float seconds, float firstTime, float interval, Action action, Action callback){ return monoBehaviour.StartCoroutine(DoCallTimer(seconds, firstTime, interval, action, callback)); } private static IEnumerator DoCallTimer(float seconds, float firstTime, float interval, Action action, Action callback){ float t = 0.0f; float timer = firstTime; int counter = 1; do{ yield return null; t += Time.deltaTime; timer += Time.deltaTime; while(timer >= interval){ timer -= interval; action(++counter); } }while(t < seconds); callback(); } public static Coroutine CallTimerRealtime(this MonoBehaviour monoBehaviour, float seconds, float interval, Action action, Action callback){ return monoBehaviour.StartCoroutine(DoCallTimerRealtime(seconds, interval, action, callback)); } private static IEnumerator DoCallTimerRealtime(float seconds, float interval, Action action, Action callback){ float startupTime = Time.realtimeSinceStartup; float t = 0.0f; int counter = 0; action(counter + 1); do{ yield return null; t = (Time.realtimeSinceStartup - startupTime); int count = (int)(t / interval); if(counter != count){ counter = count; action(counter + 1); } }while(t < seconds); callback(); } }