private static bool UpdateNonInstantEvents(StateMachineComponent stateMachine, ref List <Event> nonInstantEvents, float currentTime) { for (int i = 0; i < nonInstantEvents.Count;) { Event evnt = nonInstantEvents[i]; ITimelineStateEvent stateMachineEvent = evnt as ITimelineStateEvent; float eventTime = currentTime - evnt.GetTime(); bool timeUp = eventTime >= evnt.GetDuration(); if (timeUp) { stateMachineEvent.End(stateMachine); nonInstantEvents.RemoveAt(i); } else { eEventTriggerReturn status = stateMachineEvent.Update(stateMachine, eventTime); switch (status) { case eEventTriggerReturn.EventFinished: nonInstantEvents.RemoveAt(i); break; case eEventTriggerReturn.EventOngoing: break; case eEventTriggerReturn.EventFinishedExitState: return(true); } i++; } } return(false); }
private static IEnumerator PerformState(StateMachine stateMachine, TimelineState state, Timeline timeline) { if (timeline != null && timeline._events.Length > 0) { ITimelineStateMachineTimer timer = TimelineStateMachine.GetTimer(stateMachine.gameObject); float currentTime = 0.0f; List <Event> nonInstantEvents = new List <Event>(); int eventIndex = 0; Event currentEvent = timeline._events[eventIndex]; while (currentEvent != null || nonInstantEvents.Count > 0) { IStateMachineEvent currentStateMachineEvent = currentEvent as IStateMachineEvent; if (currentStateMachineEvent == null && currentEvent != null) { throw new System.Exception("Event doesn't implement IStateMachineEvent"); } float nextEventTime = currentEvent != null ? timeline._events[eventIndex].GetTime() : 0.0f; //Wait until event time while (currentTime < nextEventTime || (currentEvent == null && nonInstantEvents.Count > 0)) { currentTime += timer.GetDeltaTime(); #if DEBUG TimelineStateMachineDebug.OnTimelineStateTimeProgress(stateMachine, state, currentTime); #endif //Updated non instant events, if any now wants to exit the state then break out of coroutine if (UpdateNonInstantEvents(stateMachine, ref nonInstantEvents, currentTime)) { EndNonInstantEvents(stateMachine, ref nonInstantEvents); yield break; } yield return(null); } if (currentEvent == null) { break; } //Trigger event eEventTriggerReturn status = currentStateMachineEvent.Trigger(stateMachine); switch (status) { case eEventTriggerReturn.EventFinished: //Do nothing, just move on to next event break; case eEventTriggerReturn.EventFinishedExitState: //Exit state so break out of coroutine EndNonInstantEvents(stateMachine, ref nonInstantEvents); yield break; case eEventTriggerReturn.EventOngoing: //Track timed event, move on to next event nonInstantEvents.Add(currentEvent); break; } //Get next currentEvent = ++eventIndex < timeline._events.Length ? timeline._events[eventIndex] : null; } } #if DEBUG TimelineStateMachineDebug.OnTimelineStateStoped(stateMachine); #endif yield break; }