using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameStart : MonoBehaviour
{
public CallbackRunnerTest callbackRunnerTest;
private GameRoot gameRoot;
private void Start()
{
gameRoot = GameRoot.Instance;
gameRoot.DebugTest();
gameRoot.Test_RandomFloat(0.1f, 0.99f);
gameRoot.Test_RandomInt(1, 9);
gameRoot.Test_LogNewGuid();
callbackRunnerTest.RunFiveSecondsRoutine();
callbackRunnerTest.RunFiveSecondsRoutineAfter2Secs();
callbackRunnerTest.RunNormalFunctionAsCallback();
callbackRunnerTest.RunNormalFunctionAsCallbackAfter2Secs();
callbackRunnerTest.CancelLatestCoroutine();
}
private void OnDestroy()
{
gameRoot.callbackRunner.StopAllCoroutines();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ED;
public class GameRoot : BaseMonoSingleton
{
public CallbackRunner callbackRunner;
private RangedFloat rangedFloat;
private RangedInt RangedInt;
protected override void Init()
{
base.Init();
Debug.Log($"*********{this.GetType()} Init********");
}
public void DebugTest()
{
Debug.Log("*********Test********");
}
public void Test_RandomFloat(float min, float max)
{
rangedFloat = new RangedFloat
{
MinValue = min,
MaxValue = max
};
float temp_Float = rangedFloat.Random();
Debug.Log($"随机到的Float数值为:{temp_Float}");
}
public void Test_RandomInt(int min, int max)
{
RangedInt = new RangedInt
{
MinValue = min,
MaxValue = max
};
float temp_Int = RangedInt.Random();
Debug.Log($"随机到的Int数值为:{temp_Int}");
}
public void Test_LogNewGuid()
{
Debug.Log($"随机到的Guid数值为:{callbackRunner.LogGuid().ToString()}");
}
}
using ED;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CallbackRunnerTest : MonoBehaviour
{
private Guid _latestCoroutineKey;
public void RoutineStarted(Guid key)
{
Debug.Log($"[Event Received: Started] Coroutine with key {key} started.");
}
public void RoutineFinished(Guid key)
{
Debug.Log($"[Event Received: Finished]Coroutine with key {key} finished.");
}
public void RoutineStopped(Guid key)
{
Debug.Log($"[Event Received: Stopped] Coroutine with key {key} stopped.");
}
public void RunFiveSecondsRoutine()
{
_latestCoroutineKey = CallbackRunner.Instance.StartCoroutineImmediately(CountFiveSeconds);
}
public void RunFiveSecondsRoutineAfter2Secs()
{
_latestCoroutineKey = CallbackRunner.Instance.StartCoroutineAfterDelay(2, CountFiveSeconds);
}
public void RunNormalFunctionAsCallback()
{
_latestCoroutineKey = CallbackRunner.Instance.StartCoroutineImmediately(GetFirst100FibonacciNumbers);
}
public void RunNormalFunctionAsCallbackAfter2Secs()
{
_latestCoroutineKey = CallbackRunner.Instance.StartCoroutineAfterDelay(2, GetFirst100FibonacciNumbers);
}
public void CancelLatestCoroutine()
{
Debug.Log(CallbackRunner.Instance.StopCoroutine(_latestCoroutineKey)
? $"Coroutine with key {_latestCoroutineKey} stopped."
: $"Coroutine with key {_latestCoroutineKey} not found.");
}
///
/// 数五秒
///
private IEnumerator CountFiveSeconds()
{
var seconds = 0;
while (seconds < 5)
{
Debug.Log($"{seconds} seconds passed.");
yield return new WaitForSeconds(1);
seconds++;
}
}
///
/// 获得前100个斐波那契数
///
private void GetFirst100FibonacciNumbers()
{
const int count = 100;
int n1 = 0, n2 = 1, n3;
var fibonacciSequence = new List { n1, n2 }; // 列表来保存斐波那契数列
for (var i = 2; i < count; ++i)
{
n3 = n1 + n2;
fibonacciSequence.Add(n3);
n1 = n2;
n2 = n3;
}
// 用空格分隔符连接列表中的所有数字并打印它们
Debug.Log($"First {count} Fibonacci numbers:");
Debug.Log(string.Join(" ", fibonacciSequence));
}
}
using UnityEngine;
namespace ED
{
public abstract class BaseMonoSingleton : MonoBehaviour where T : BaseMonoSingleton
{
private static T _instance;
public static T Instance => _instance;
protected virtual void Awake()
{
if (_instance != null && _instance != this)
{
Destroy(gameObject);
return;
}
_instance = (T)this;
Init();
}
protected virtual void Init() { }
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace ED
{
///
/// 只读属性。使用这个属性使一个字段在检查器中只能读取。
///
public class InspectorReadOnlyAttribute : PropertyAttribute { }
public class CallbackRunner : BaseMonoSingleton
{
///
///当协程启动时调用。
/// Guid是协程的Key。
///
[SerializeField]
private UnityEvent onCoroutineStarted;
///
///在协程完成时调用。
/// Guid是协程的Key。
///
[SerializeField] private UnityEvent onCoroutineFinished;
///
///当协程被代码停止时调用。
/// Guid是协程的Key。
///
[SerializeField] private UnityEvent onCoroutineStopped;
private bool IsCoroutineCancelled(Guid key) => !_routineIDict.ContainsKey(key);
private static Guid GetCoroutineKey() => Guid.NewGuid();
private IDictionary _routineIDict;
[Space(10), Header("Debug Settings")]
[SerializeField]
private bool enableDebugLog;
[SerializeField]
private bool enableRoutineKeyRuntimeInfo;
[SerializeField, InspectorReadOnly]
private List runningCoroutineKeys;
protected override void Init()
{
base.Init();
_routineIDict = new Dictionary();
}
///
/// 立即启动一个协程,并返回一个键,可以用来稍后取消这个协程。
///
public Guid StartCoroutineImmediately(Func coroutine)
{
var newKey = GetCoroutineKey();
StartCoroutine(StartManagedCoroutine(coroutine, newKey));
return newKey;
}
///
/// 立即启动协程并返回可用于稍后取消该例程的键。
///
/// 将在协程中执行的操作
public Guid StartCoroutineImmediately(Action action)
{
var newKey = GetCoroutineKey();
StartCoroutine(StartManagedCoroutine(WrapActionInEnumerator(action), newKey));
return newKey;
}
///
/// 将在延迟后运行。该协程的键将立即返回。
///
/// 运行操作之前的等待时间。
/// 将被执行的委派。
public Guid StartCoroutineAfterDelay(float delay, Action action)
{
var newKey = GetCoroutineKey();
StartCoroutine(StartManagedCoroutine(WrapActionInEnumerator(action), newKey, delay));
return newKey;
}
///
/// 将在延迟后运行。该协程的键将立即返回。
///
public Guid StartCoroutineAfterDelay(float delay, Func routine)
{
var newKey = GetCoroutineKey();
StartCoroutine(StartManagedCoroutine(routine, newKey, delay));
return newKey;
}
///
/// 尝试根据提供的键停止协程。
///
/// Coroutine key
/// 如果键存在并且例程已停止,则为True,否则为false。
public bool StopCoroutine(Guid coroutineKey)
{
if (coroutineKey == Guid.Empty || !_routineIDict.ContainsKey(coroutineKey)) return false;
StopCoroutine(_routineIDict[coroutineKey]);
Log($"Coroutine '{coroutineKey}' stopped");
onCoroutineStopped?.Invoke(coroutineKey);
RemoveCoroutine(coroutineKey);
return true;
}
public void StopCoroutine()
{
foreach (Guid item in _routineIDict.Keys)
{
StopCoroutine(item);
}
}
public Guid LogGuid()
{
var newKey = GetCoroutineKey();
return newKey;
}
#region 私有函数
private void Log(string message)
{
if (!enableDebugLog) return;
Debug.Log(message);
}
private IEnumerator StartManagedCoroutine(Func action, Guid coroutineKey, float? delay = null)
{
if (!IsCoroutineCancelled(coroutineKey)) yield break;
if (delay.HasValue)
{
Log($"将例行程序延迟{delay.Value}秒开始");
var delayCoroutine = StartCoroutine(WaitForDelay(delay.Value));
RegisterNewCoroutine(coroutineKey, delayCoroutine);
yield return delayCoroutine;
RemoveCoroutine(coroutineKey);
}
Log($"Coroutine '{coroutineKey}' started");
onCoroutineStarted.Invoke(coroutineKey);
var coroutine = StartCoroutine(action());
RegisterNewCoroutine(coroutineKey, coroutine);
yield return coroutine;
Log($"Coroutine '{coroutineKey}' finished");
onCoroutineFinished?.Invoke(coroutineKey);
RemoveCoroutine(coroutineKey);
}
private static IEnumerator WaitForDelay(float delay)
{
yield return new WaitForSeconds(delay);
}
///
/// 注册新的协程
///
private void RegisterNewCoroutine(Guid coroutineKey, Coroutine runningCoroutine)
{
_routineIDict.Add(coroutineKey, runningCoroutine);
if (!enableRoutineKeyRuntimeInfo) return;
runningCoroutineKeys.Add(coroutineKey.ToString());
}
private void RemoveCoroutine(Guid coroutineKey)
{
if (!IsCoroutineCancelled(coroutineKey))
{
_routineIDict.Remove(coroutineKey);
}
if (!enableRoutineKeyRuntimeInfo) return;
runningCoroutineKeys.Remove(coroutineKey.ToString());
}
private static Func WrapActionInEnumerator(Action action)
{
IEnumerator Wrapper()
{
action();
yield return null;
}
return Wrapper;
}
#endregion
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace ED
{
public abstract class RangedNumeric where T : struct
{
public T MinValue;
public T MaxValue;
public abstract T Random();
}
///
/// 包含MaxValue的float类型
///
public class RangedFloat : RangedNumeric
{
public override float Random()
{
return UnityEngine.Random.Range(MinValue, MaxValue);
}
}
///
/// 包含MaxValue的int类型
///
public class RangedInt : RangedNumeric
{
public override int Random()
{
return UnityEngine.Random.Range(MinValue, MaxValue + 1);
}
}
}