diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index 46ec125..435a28f 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -95,15 +95,14 @@ //标记字典 private Dictionary _signMap; - private List> _coroutineList; + private List _coroutineList; private ActivityObjectTemplate _templateInstance; - private static long _coroutineId = 0; - private static long _index = 0; + private static long _instanceIndex = 0; public ActivityObject(string scenePath) { - Name = GetType().Name + (_index++); + Name = GetType().Name + (_instanceIndex++); //加载预制体 var tempPrefab = ResourceManager.Load(scenePath); if (tempPrefab == null) @@ -624,13 +623,62 @@ for (var i = 0; i < pairs.Length; i++) { var item = pairs[i]; - if (!item.Value.MoveNext()) + var canNext = true; + + if (item.WaitType == CoroutineData.WaitTypeEnum.WaitForSeconds) //等待秒数 { - StopCoroutine(item.Key); + if (!item.WaitForSeconds.NextStep(newDelta)) + { + canNext = false; + } + } + else if (item.WaitType == CoroutineData.WaitTypeEnum.WaitForFixedProcess) //等待帧数 + { + if (!item.WaitForFixedProcess.NextStep()) + { + canNext = false; + } + } + + if (canNext) + { + if (item.Enumerator.MoveNext()) //嵌套协程 + { + var next = item.Enumerator.Current; + if (next is IEnumerator enumerator) + { + if (item.EnumeratorStack == null) + { + item.EnumeratorStack = new Stack(); + } + + item.EnumeratorStack.Push(item.Enumerator); + item.Enumerator = enumerator; + } + else if (next is WaitForSeconds seconds) //等待秒数 + { + item.WaitFor(seconds); + } + else if (next is WaitForFixedProcess process) //等待帧数 + { + item.WaitFor(process); + } + } + else + { + if (item.EnumeratorStack == null || item.EnumeratorStack.Count == 0) + { + StopCoroutine(item.Id); + } + else + { + item.Enumerator = item.EnumeratorStack.Pop(); + } + } } } } - + ProcessOver(newDelta); //调试绘制 @@ -759,20 +807,6 @@ CallDeferred(nameof(Destroy)); } - //返回该组件是否被挂载到当前物体上 - private bool ContainsComponent(Component component) - { - for (int i = 0; i < _components.Count; i++) - { - if (_components[i].Value == component) - { - return true; - } - } - - return false; - } - /// /// 触发投抛动作 /// @@ -953,17 +987,18 @@ } /// - /// 开启一个协程, 返回协程 id + /// 开启一个协程, 返回协程 id, 协程是在普通帧执行的, 支持: 协程嵌套, WaitForSeconds, WaitForFixedProcess /// public long StartCoroutine(IEnumerable able) { - var id = _coroutineId++; if (_coroutineList == null) { - _coroutineList = new List>(); + _coroutineList = new List(); } - _coroutineList.Add(new KeyValuePair(id, able.GetEnumerator())); - return id; + + var data = new CoroutineData(able.GetEnumerator()); + _coroutineList.Add(data); + return data.Id; } /// @@ -976,7 +1011,7 @@ for (var i = 0; i < _coroutineList.Count; i++) { var item = _coroutineList[i]; - if (item.Key == coroutineId) + if (item.Id == coroutineId) { _coroutineList.RemoveAt(i); return; diff --git a/DungeonShooting_Godot/src/framework/activity/CoroutineData.cs b/DungeonShooting_Godot/src/framework/activity/CoroutineData.cs new file mode 100644 index 0000000..b2f1225 --- /dev/null +++ b/DungeonShooting_Godot/src/framework/activity/CoroutineData.cs @@ -0,0 +1,41 @@ + +using System.Collections; +using System.Collections.Generic; + +public class CoroutineData +{ + private static long _id; + + public enum WaitTypeEnum + { + None, + WaitForSeconds, + WaitForFixedProcess, + } + + public readonly long Id; + public WaitTypeEnum WaitType = WaitTypeEnum.None; + public IEnumerator Enumerator; + public Stack EnumeratorStack; + + public WaitForSeconds WaitForSeconds; + public WaitForFixedProcess WaitForFixedProcess; + + public CoroutineData(IEnumerator enumerator) + { + Id = _id++; + Enumerator = enumerator; + } + + public void WaitFor(WaitForSeconds seconds) + { + WaitType = WaitTypeEnum.WaitForSeconds; + WaitForSeconds = seconds; + } + + public void WaitFor(WaitForFixedProcess process) + { + WaitType = WaitTypeEnum.WaitForFixedProcess; + WaitForFixedProcess = process; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/activity/WaitForFixedProcess.cs b/DungeonShooting_Godot/src/framework/activity/WaitForFixedProcess.cs new file mode 100644 index 0000000..6bcb96e --- /dev/null +++ b/DungeonShooting_Godot/src/framework/activity/WaitForFixedProcess.cs @@ -0,0 +1,19 @@ + +/// +/// 用于协程返回, 表示当前协程等待指定帧数 +/// +public class WaitForFixedProcess +{ + private float _frames; + private float _current = 0; + + public WaitForFixedProcess(int frames) + { + _frames = frames; + } + + public bool NextStep() + { + return _current++ >= _frames; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/activity/WaitForSeconds.cs b/DungeonShooting_Godot/src/framework/activity/WaitForSeconds.cs new file mode 100644 index 0000000..3da00fc --- /dev/null +++ b/DungeonShooting_Godot/src/framework/activity/WaitForSeconds.cs @@ -0,0 +1,25 @@ + +/// +/// 用于协程返回, 表示当前协程等待指定秒数 +/// +public class WaitForSeconds +{ + private float _timer; + private float _current = 0; + + public WaitForSeconds(float time) + { + _timer = time; + } + + public bool NextStep(float delta) + { + if (_current >= _timer) + { + return true; + } + + _current += delta; + return false; + } +} \ No newline at end of file