/// <summary>
        /// Update the animation/FSM state for the player.
        /// </summary>
        /// <param name="player">The player character.</param>
        /// <param name="driver">The state driver for the target state.</param>
        /// <param name="playable">The playable associated with this clip.</param>
        /// <param name="pose">Information about the player's pose.</param>
        private void UpdateState(PlayerCharacter player, StateDriver driver, Playable playable, PoseInfo pose)
        {
            if (driver == null)
            {
                return;
            }

      #if UNITY_EDITOR
            if (Application.isPlaying)
            {
      #endif

            if (!driver.IsInState(player.FSM))
            {
                driver.ForceStateChangeOn(player.FSM);
            }

      #if UNITY_EDITOR
        }

        else
        {
            // In-Editor we don't want to actually change the Finite State Machine,
            // so just play the appropriate animation.
            float totalTrackTime    = (float)playable.GetTime();
            float currentTimeInClip = totalTrackTime - pose.StartTime;

            driver.SampleClip(player.FSM, currentTimeInClip);
        }
      #endif
        }
        public void StartMachine(Type startState = null)
        {
            if (startState == null)
            {
                startState = Type.GetType(StartingState);
            }

            startingStateDriver = StateDriver.For(startState);
            startingStateDriver.StartMachine(this);
        }
        //-------------------------------------------------------------------------
        // Helper Methods
        //-------------------------------------------------------------------------

        /// <summary>
        /// Get the state driver for the current state.
        /// </summary>
        /// <param name="pose">The pose clip.</param>
        /// <returns>The state driver for the current state.</returns>
        private StateDriver GetDriver(PoseInfo pose)
        {
            if (pose == null || pose.State == null)
            {
                return(null);
            }

            if (!stateDrivers.ContainsKey(pose.State))
            {
                stateDrivers.Add(pose.State, StateDriver.For(pose.State));
            }
            return(stateDrivers[pose.State]);
        }
示例#4
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="player">The player character.</param>
 public PlayerSnapshot(PlayerCharacter player)
 {
     if (player != null)
     {
         driver         = StateDriver.For(player.FSM.CurrentState);
         position       = player.transform.position;
         rotation       = player.transform.eulerAngles;
         scale          = player.transform.localScale;
         facing         = player.Facing;
         active         = player.gameObject.activeSelf;
         sprite         = player.Sprite.sprite;
         colliderSize   = player.Collider.size;
         colliderOffset = player.Collider.offset;
     }
 }
        //-------------------------------------------------------------------------
        // Auto Node API
        //-------------------------------------------------------------------------
        public override void Handle(GraphEngine graphEngine)
        {
            if (State != null)
            {
                Type t = Type.GetType(State);

                if (t != null)
                {
                    StateDriver driver = StateDriver.For(State);
                    if (!driver.IsInState(GameManager.Player.FSM))
                    {
                        driver.ForceStateChangeOn(player.FSM);
                    }
                }
            }
        }
        //-------------------------------------------------------------------------
        // Clip Mixing
        //-------------------------------------------------------------------------

        /// <summary>
        /// Mix a single clip.
        /// </summary>
        /// <param name="playable">The track's playable</param>
        /// <param name="player">The player character</param>
        /// <param name="clipIndex">The index of the clip to mix</param>
        private void MixSingle(Playable playable, PlayerCharacter player, int clipIndex)
        {
            PoseInfo pose = TimelineTools.GetClipInfo <PoseInfo>(playable, clipIndex);

            player.gameObject.SetActive(pose.Active);

            if (PoseTools.IsAbsolute(pose)) // Absolute
            {
                MixAbsolute(player, (AbsolutePoseInfo)pose);
            }
            else // Relative
            {
                VirtualSnapshot.RestoreTransform(player);
                MixRelative(player, (RelativePoseInfo)pose);
            }

            StateDriver driver = GetDriver(pose);

            UpdateFacing(player, pose);
            UpdateState(player, driver, playable, pose);
        }
        /// <summary>
        /// Mix together two active clips based on what type of clips they are.
        /// </summary>
        /// <param name="playable">The track's playable</param>
        /// <param name="player">The player character</param>
        /// <param name="clipIndexA">The index of the first clip to mix</param>
        /// <param name="clipIndexB">The index of the second clip to mix</param>
        private void MixMultiple(Playable playable, PlayerCharacter player, int clipIndexA, int clipIndexB)
        {
            PoseInfo poseA   = TimelineTools.GetClipInfo <PoseInfo>(playable, clipIndexA);
            float    weightA = playable.GetInputWeight(clipIndexA);

            PoseInfo poseB   = TimelineTools.GetClipInfo <PoseInfo>(playable, clipIndexB);
            float    weightB = playable.GetInputWeight(clipIndexB);

            // Mix together clips based on their typing.
            if (PoseTools.IsAbsolute(poseA) && PoseTools.IsAbsolute(poseB))
            {
                MixAbsolute(player, (AbsolutePoseInfo)poseA, weightA);
                MixAbsolute(player, (AbsolutePoseInfo)poseB, weightB);
            }
            else if (PoseTools.IsRelative(poseA) && PoseTools.IsRelative(poseB))
            {
                VirtualSnapshot.RestoreTransform(player);

                RelativePoseInfo mixed = new RelativePoseInfo();
                mixed.Position = poseA.Position * weightA + poseB.Position * weightB;
                mixed.Rotation = poseA.Rotation * weightA + poseB.Rotation * weightB;
                mixed.Scale    = poseA.Scale * weightA + poseB.Scale * weightB;

                MixRelative(player, mixed);
            }
            else
            {
                MixAbsoluteRelative(player, poseA, weightA, poseB, weightB);
            }

            // Apply player facing and FSM state based on which pose is weighted heavier.
            PoseInfo dominantPose = weightA > weightB ? poseA : poseB;

            player.gameObject.SetActive(dominantPose.Active);
            StateDriver driver = GetDriver(dominantPose);

            UpdateFacing(player, dominantPose);
            UpdateState(player, driver, playable, dominantPose);
        }