public override BaseNode Copy() { StateMachineNode copy = new StateMachineNode() { Name = Name, Speed = Speed }; var valueProviderCopyMap = new Dictionary <IValueProvider, IValueProvider>(); Parameters.Values.ForEach(p => { var parameterCopy = copy.AddParameter(p.Copy()); valueProviderCopyMap.Add(p.ValueProvider, parameterCopy.ValueProvider); }); var copiedStates = new Dictionary <BaseState, BaseState>(); var copiedTransitions = new Dictionary <Transition, Transition>(); var transitionsToSetSource = new List <(Transition copy, BaseState originalSource)>(); var transitionsToSetDestination = new List <(Transition copy, State originalDestination)>(); var conditionsToSetValueProvider = new List <(TransitionCondition copy, IValueProvider originalValueProvider)>(); Transition CopyTransition(Transition original) { if (copiedTransitions.ContainsKey(original)) { return(copiedTransitions[original]); } Transition transitionCopy = original.Copy(copiedStates, valueProviderCopyMap); copy.Transitions.Add(transitionCopy); copiedTransitions.Add(original, transitionCopy); if (transitionCopy.SourceState == null) { transitionsToSetSource.Add((transitionCopy, original.SourceState)); } if (transitionCopy.DestinationState == null) { transitionsToSetDestination.Add((transitionCopy, original.DestinationState)); } return(transitionCopy); } States.Values.ForEach(s => { State stateCopy = (State)s.Copy(CopyTransition, valueProviderCopyMap); copy.AddState(stateCopy); copiedStates.Add(s, stateCopy); }); AnyStates.Items.Values.ForEach(s => { AnyState anyStateCopy = (AnyState)s.Copy(CopyTransition); s.StateFilters.ForEach(f => anyStateCopy.StateFilters.Add(new AnyStateFilter() { State = (State)copiedStates[f.State], Mode = f.Mode })); copy.AnyStates.AddItem(s.Name, anyStateCopy); copiedStates.Add(s, anyStateCopy); }); copy.EntryState = (State)copiedStates[EntryState]; transitionsToSetSource.ForEach(t => t.copy.SourceState = copiedStates[t.originalSource]); transitionsToSetDestination.ForEach(t => t.copy.DestinationState = (State)copiedStates[t.originalDestination]); return(copy); }
public void Update(float deltaTime) { if (CurrentState == null) { return; } if (!InTransition || CurrentTransition.InterruptableByAnyState) { int index = InTransition && CurrentTransition.SourceState is AnyState?AnyStates.Items.Values.IndexOf((AnyState)CurrentTransition.SourceState) : AnyStates.Items.Count - 1; for (int i = 0; i <= index; i++) { AnyState anyState = AnyStates.Items.At(i); AnyStateFilter currentStateFilter = anyState.StateFilters.Find(f => f.State == CurrentState); AnyStateFilter nextStateFilter = anyState.StateFilters.Find(f => f.State == NextState); if ((currentStateFilter == null || currentStateFilter.Mode == AnyStateFilterMode.NextState) && (NextState == null || nextStateFilter == null || nextStateFilter.Mode == AnyStateFilterMode.CurrentState)) { continue; } Transition evaluatedTransition = null; if (InTransition && CurrentTransition.SourceState == anyState) { evaluatedTransition = EvaluateTransitions(anyState, anyState.ExitTransitions.IndexOf(CurrentTransition)); } else { evaluatedTransition = EvaluateTransitions(anyState); } if (evaluatedTransition != null) { StartTransition(evaluatedTransition); break; } } } Transition transition = null; for (int i = 0; i < States.Count; i++) { if (Playable.GetInputWeight(i) > 0f) { State state = States.At(i); //state.PreviousTime.Value = state.Time.Value; //state.PreviousNormalizedTime.Value = state.NormalizedTime.Value; BaseNode node = InputPorts[i].Link != null ? InputPorts[i].Link.OutputPort.Node : null; if (!state.ManualTime) { if (node != null) { float trueDeltaTime = deltaTime * (node.RawDuration / node.Duration); state.PassTime(trueDeltaTime); state.PassNormalizedTime(trueDeltaTime / node.RawDuration); //state.Time.Value += trueDeltaTime; //state.NormalizedTime.Value += trueDeltaTime / node.RawDuration; } else { state.PassTime(deltaTime); state.PassNormalizedTime(deltaTime); //state.Time.Value += deltaTime; //state.NormalizedTime.Value += deltaTime; } } state.Events?.ForEach(evt => { if (state.PreviousNormalizedTime.Value <= evt.NormalizedTime && state.NormalizedTime.Value >= evt.NormalizedTime) { evt.Callback(evt.NormalizedTime, state); } }); state.ContinousEvents?.ForEach(evt => { if (state.NormalizedTime.Value >= evt.StartTime && (state.NormalizedTime.Value <= evt.EndTime || state.PreviousNormalizedTime.Value <= evt.EndTime)) { evt.Callback(state, evt); } }); } } if (InTransition) { if (CurrentTransition.InterruptionSource != TransitionInterruptionSource.None && !(CurrentTransition.SourceState is AnyState)) { switch (CurrentTransition.InterruptionSource) { case TransitionInterruptionSource.CurrentState: { int currentTransitionIndex = CurrentTransition.OrderedInterruption ? CurrentState.ExitTransitions.IndexOf(CurrentTransition) : -1; if (currentTransitionIndex != 0) { EvaluateTransitions(CurrentState, currentTransitionIndex); } break; } case TransitionInterruptionSource.NextState: EvaluateTransitions(NextState); break; case TransitionInterruptionSource.CurrentThenNextState: { int currentTransitionIndex = CurrentTransition.OrderedInterruption ? CurrentState.ExitTransitions.IndexOf(CurrentTransition) : -1; if (currentTransitionIndex == 0 || ((transition = EvaluateTransitions(CurrentState, currentTransitionIndex)) != null)) { transition = EvaluateTransitions(NextState); } break; } case TransitionInterruptionSource.NextThenCurrentState: if ((transition = EvaluateTransitions(NextState)) != null) { int currentTransitionIndex = CurrentTransition.OrderedInterruption ? CurrentState.ExitTransitions.IndexOf(CurrentTransition) : -1; if (currentTransitionIndex != 0) { EvaluateTransitions(CurrentState, currentTransitionIndex); } } break; } } UpdateTransition(deltaTime); } else { transition = EvaluateTransitions(CurrentState); } _triggersToReset.ForEach(t => t.Value = false); _triggersToReset.Clear(); if (transition != null) { StartTransition(transition); } }