• RuntimesUnity
  • Blending different pose based on mouse position with SpineSkeleton

Hi! I'm trying to blend different static poses for a skeleton within Unity, based on mouse position. I'm currently achieving this using Spine Mechanim with the standard unity animator controller, but I'm wondering how to achieve the same effect using Spine Skeleton and animations Track.

The setup is the following (Mechanim): I have an Idle animation that is played in loop in a base animator layer, then another layer that overrides some bones position, which contains a blend tree that blend 4 static animation based on XY parameters.

If I would use SpineSkeleton, I assume I would have to use Tracks, but how to blend 4 static animation at the same time? Do I have to use 4 different tracks?

  • Misaki ha risposto a questo messaggio
    Related Discussions
    ...

    To achieve blending of different static poses based on mouse position using Spine Skeleton and animation tracks, you can utilize multiple tracks and the TrackEntry.Alpha property to blend between them. Here's a general approach:

    1. Set Up Base Animation: Play your idle animation on track 0. This will serve as the base animation.

    2. Use Additional Tracks for Poses: For each static pose you want to blend, use a separate track. For example, if you have four static poses, you would use tracks 1 to 4.

    3. Blend Using Alpha: Adjust the Alpha property of each TrackEntry to control the blending between these poses. The Alpha value determines how much influence each track has on the final pose. You can dynamically adjust these values based on the mouse position.

    4. Calculate Blending: Based on the mouse position, calculate the blending weights for each pose. You can use a simple interpolation or a more complex function depending on your needs.

    Here's a basic example of how you might set this up in code:

    _skeletonAnimation.Skeleton.SetToSetupPose();
    _skeletonAnimation.AnimationState.SetAnimation(0, "idle", true);
    
    TrackEntry pose1 = _skeletonAnimation.AnimationState.SetAnimation(1, "pose1", false);
    TrackEntry pose2 = _skeletonAnimation.AnimationState.SetAnimation(2, "pose2", false);
    TrackEntry pose3 = _skeletonAnimation.AnimationState.SetAnimation(3, "pose3", false);
    TrackEntry pose4 = _skeletonAnimation.AnimationState.SetAnimation(4, "pose4", false);
    
    // Example: Set alpha based on mouse position
    pose1.Alpha = CalculateAlphaForPose1(mousePosition);
    pose2.Alpha = CalculateAlphaForPose2(mousePosition);
    pose3.Alpha = CalculateAlphaForPose3(mousePosition);
    pose4.Alpha = CalculateAlphaForPose4(mousePosition);

    This setup allows you to blend between multiple static poses by adjusting the Alpha values based on the mouse position.

    Gomi91 In SkeletonMechanim, the animation layer corresponds to the animation track, so there is no need to use another track concept in addition to the animation layer.
    If you want to use the AnimationState track, you have to use the SkeletonAnimation component. That's why Spinebot replied with the code to use the SkeletonAnimation component.

    The following thread may be helpful to you:
    https://esotericsoftware.com/forum/d/26314-mixing-track--animations/3

    • Gomi91 ha risposto a questo messaggio

      Misaki Yup, thanks it works!

      4 giorni dopo

      Ok, I have another question: in C#, I can declare two varaibles of type TrackEntry. Then I can call SetAnimation() on AnimationState object, and use the very same Track index, set the alpha of the two EntryTrack and the result eventually is a blend of the two animations. How does it works? I tought there could be only one animation per track index, I'm a bit confused.
      This is a snippet on the code executed during start.

      skeletonAnimation = GetComponent<SkeletonAnimation>();
      spineAnimationState = skeletonAnimation.AnimationState;
      
      skeletonAnimation.Skeleton.SetToSetupPose();
      skeletonAnimation.AnimationState.SetAnimation(0, BaseIdle, true);
      
      pose1 = skeletonAnimation.AnimationState.SetAnimation(1, Up, true);
      pose2 = skeletonAnimation.AnimationState.SetAnimation(1, Down, true);

      This is a coroutine to manage the alpha:

      private IEnumerator ManageTouch()
      {
      	while (true)
      	{
      		var alpha = GetTracksAlphaValues();
      		pose1.Alpha = alpha.A;
      		pose2.Alpha = alpha.B;
      
      		yield return null;
      	}
      }
      • Misaki ha risposto a questo messaggio

        Gomi91

        Then I can call SetAnimation() on AnimationState object, and use the very same Track index, set the alpha of the two EntryTrack and the result eventually is a blend of the two animations.

        Hmmm, I am not sure how that could be the result, because as you mentioned, a track can only play one animation. It is not possible to have two animations on track 1 at the same time and have them blend together. However, since you can queue animations on the same track, it is possible to have multiple animations set in sequence and blend them together during mixing. As far as I can see from your code, you set the two animations for the same track by SetAnimation, not AddAnimation, so simply only the last animation applied (Down) should remain on that track, but if you have other parts of the code that re-set the animations, then the mix may have occurred many times, resulting in the appearance of blending.

        In any case, it generally does not make sense to set animations for the same track at the same time with SetAnimation, so this practice should be avoided.

        By the way, as noted in the documentation, the returned track entries will only be valid until the corresponding animation is removed from the underlying animation state. After a dispose event is received for a track entry, it should no longer be stored or accessed.