Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
            }
        }