public AnimationStateMachine(AnimationPackage package) { horizMovement = Vector2.Zero; mSkinningData = package.SkinningData; // Use the data in the AnimationPackage structure to create states to fill our list and build // a transition matrix. states = new Dictionary<string, AnimationState>(); foreach (AnimationStateDescription stateDesc in package.StateDescriptions) { AnimationState newState = new AnimationState(stateDesc, package); states.Add(newState.Name, newState); } transitions = new Dictionary<AnimationState, Dictionary<AnimationState, TransitionInfo>>(); foreach (KeyValuePair<string, AnimationState> currentStateKvp in states) { transitions.Add(currentStateKvp.Value, new Dictionary<AnimationState, TransitionInfo>()); foreach (KeyValuePair<string, AnimationState> nextStateKvp in states) { TransitionInfo bestFitTransition = null; foreach (TransitionInfo ti in package.Transitions) { // The items lower in the list are higher priority and will override previous matches. if (ti.IsMatch(currentStateKvp.Key, nextStateKvp.Key)) bestFitTransition = ti; } transitions[currentStateKvp.Value].Add(nextStateKvp.Value, bestFitTransition); } } CurrentState = states[package.InitialStateName]; desiredState = CurrentState; ActiveTransition = null; nextState = null; blendFromCancelledTransitionPose = false; ActiveControlEvents = AnimationControlEvents.None; }
/// <summary> /// Advance the currently playing clips, transitions, etc, and return any metachannel events that /// have occurred during the elapsed time. /// </summary> /// <param name="gameTime"></param> /// <returns></returns> public void Update(GameTime gameTime) { ActiveControlEvents = AnimationControlEvents.None; if (ActiveTransition == null || (transitionTime == TimeSpan.Zero && !CurrentState.CanTransitionOut())) { // We're either completely in a given state, or we can't begin the transition just yet. CurrentState.AdvanceTime(gameTime.ElapsedGameTime); ActiveControlEvents |= CurrentState.GetActiveControlEvents(); } else { // A transition is in progress. if (ActiveTransition.Type != TransitionType.Frozen) { CurrentState.AdvanceTime(gameTime.ElapsedGameTime); ActiveControlEvents |= CurrentState.GetActiveControlEvents(); } nextState.AdvanceTime(gameTime.ElapsedGameTime); ActiveControlEvents |= nextState.GetActiveControlEvents(); transitionTime += gameTime.ElapsedGameTime; // Has the transition completed? if (transitionTime.TotalSeconds >= ActiveTransition.DurationInSeconds) { CurrentState = nextState; blendFromCancelledTransitionPose = false; if (nextState != desiredState) { nextState = desiredState; } else { nextState = null; } UpdateTransition(); } } }