popcorn/Scripts/Extensions/MonoBehaviourExtensions.cs

259 lines
11 KiB
C#

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<float> act, Action callback){
return monoBehaviour.StartCoroutine(DoCallWaitForSeconds(seconds, act, callback));
}
private static IEnumerator DoCallWaitForSeconds(float seconds, Action<float> 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<float> act, Action callback){
return monoBehaviour.StartCoroutine(DoCallWaitForRealTimeSeconds(seconds, act, callback));
}
private static IEnumerator DoCallWaitForRealTimeSeconds(float seconds, Action<float> 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<float> act){
return monoBehaviour.CallLerp(duration, act, ActionExtensions.EmptyAction);
}
public static Coroutine CallLerp(this MonoBehaviour monoBehaviour, float duration, Action<float> act, Action callback){
return monoBehaviour.StartCoroutine(DoCallLerp(duration, act, callback));
}
public static IEnumerator DoCallLerp(float duration, Action<float> act){
return DoCallLerp(duration, act, ActionExtensions.EmptyAction);
}
public static IEnumerator DoCallLerp(float duration, Action<float> 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<float> act){
return monoBehaviour.CallFixedLerp(duration, act, ActionExtensions.EmptyAction);
}
public static Coroutine CallFixedLerp(this MonoBehaviour monoBehaviour, float duration, Action<float> act, Action callback){
return monoBehaviour.StartCoroutine(DoCallFixedLerp(duration, act, callback));
}
public static IEnumerator DoCallFixedLerp(float duration, Action<float> act){
return DoCallFixedLerp(duration, act, ActionExtensions.EmptyAction);
}
public static IEnumerator DoCallFixedLerp(float duration, Action<float> 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<float> act){
return monoBehaviour.CallFixedLerpRealTime(duration, act, ActionExtensions.EmptyAction);
}
public static Coroutine CallFixedLerpRealTime(this MonoBehaviour monoBehaviour, float duration, Action<float> act, Action callback){
return monoBehaviour.StartCoroutine(DoCallFixedLerpRealTime(duration, act, callback));
}
public static IEnumerator DoCallFixedLerpRealTime(float duration, Action<float> act){
return DoCallFixedLerpRealTime(duration, act, ActionExtensions.EmptyAction);
}
public static IEnumerator DoCallFixedLerpRealTime(float duration, Action<float> 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<float> act){
return monoBehaviour.CallLerpSmooth(duration, act, ActionExtensions.EmptyAction);
}
public static Coroutine CallLerpSmooth(this MonoBehaviour monoBehaviour, float duration, Action<float> act, Action callback){
return monoBehaviour.StartCoroutine(DoCallLerpSmooth(duration, act, callback));
}
public static IEnumerator DoCallLerpSmooth(float duration, Action<float> act){
return DoCallLerpSmooth(duration, act, ActionExtensions.EmptyAction);
}
public static IEnumerator DoCallLerpSmooth(float duration, Action<float> 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<float> act){
return monoBehaviour.CallLerpRealtime(duration, act, ActionExtensions.EmptyAction);
}
public static Coroutine CallLerpRealtime(this MonoBehaviour monoBehaviour, float duration, Action<float> act, Action callback){
return monoBehaviour.StartCoroutine(DoCallLerpRealtime(duration, act, callback));
}
public static IEnumerator DoCallLerpRealtime(float duration, Action<float> act){
return DoCallLerpRealtime(duration, act, ActionExtensions.EmptyAction);
}
public static IEnumerator DoCallLerpRealtime(float duration, Action<float> 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<int> action){
return monoBehaviour.CallTimer(seconds, 0.0f, interval, action, ActionExtensions.EmptyAction);
}
public static Coroutine CallTimer(this MonoBehaviour monoBehaviour, float seconds, float interval, Action<int> 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<int> action){
return monoBehaviour.CallTimer(seconds, firstTime, interval, action, ActionExtensions.EmptyAction);
}
public static Coroutine CallTimer(this MonoBehaviour monoBehaviour, float seconds, float firstTime, float interval, Action<int> action, Action callback){
return monoBehaviour.StartCoroutine(DoCallTimer(seconds, firstTime, interval, action, callback));
}
private static IEnumerator DoCallTimer(float seconds, float firstTime, float interval, Action<int> 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<int> action, Action callback){
return monoBehaviour.StartCoroutine(DoCallTimerRealtime(seconds, interval, action, callback));
}
private static IEnumerator DoCallTimerRealtime(float seconds, float interval, Action<int> 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();
}
}