• Runtimes
  • How to Blend from Separate Animations to a Full Body Animation

Hello, I'm working on a project using Spine and Unity, and I'm encountering an issue with blending animations. Here are the details of my setup:

Unity Version: 2022.3.17f1
Spine SDK Version: 4.2

Question

In my current setup, I have lower body animations playing on Track 0 and upper body animations on Track 1 in Spine. I want to transition to a full body animation on Track 0, but I'm struggling to find a way to smoothly blend both the upper and lower body animations. Is there a method to achieve this?

Background:

In our project, we have both walking and attacking motions. The walking motion involves swinging arms and legs, while the attacking motion involves holding a gun with both hands. We received a request to allow attacking while walking, and I was asked if we needed to create both a walking attack motion and a regular attack motion. I suggested that we could blend animations by creating separate upper body and lower body animations.

We successfully created an upper body attack animation and a lower body walking animation, achieving the desired movement. However, when transitioning back to the full body walking motion, the blend feels awkward. I would like to know how to return to the full body animation without any noticeable issues.

What I've Tried:

SkeletonAnimation.AnimationState.ClearTrack(1);
This causes the upper body motion to freeze, resulting in an awkward mix.

SkeletonAnimation.AnimationState.SetEmptyAnimation(1, 0.25f);
This briefly returns to a default state, which can feel awkward depending on the motion.

Adjusting the MixDuration of SetEmptyAnimation
This sometimes improves or worsens the transition depending on the motion.

Setting an animation with no keys on Track 1 using SetAnimation
This results in a similar effect as SetEmptyAnimation.

If No Good Solution Exists:

1.Create all animations as full body animations.
2.Create all animations as separate upper and lower body animations.
I believe option 2 might be better due to reusability, but I would appreciate any advice on which approach is preferable.

(I'm using GPT for translation as I'm not confident in my English. I apologize for any mistakes.)

    Related Discussions
    ...

    To achieve a smooth transition from separate upper and lower body animations to a full body animation in Spine and Unity, you can follow these steps:

    1. Use Separate Animations for Upper and Lower Body: As you have already done, create separate animations for the upper and lower body parts. This allows you to blend them independently.

    2. Blend to Full Body Animation: When transitioning to a full body animation, you need to ensure that the transition is smooth. Here are some methods to achieve this:

      • Set Empty Animation on Track 1: This is a common approach, but as you mentioned, it can sometimes result in an awkward transition. To improve this, you can adjust the mix duration to make the transition smoother. For example:

             skeletonAnimation.AnimationState.SetEmptyAnimation(1, 0.5f); // Adjust the duration as needed
      • Use MixBlend Modes: Utilize the MixBlend modes to control how the animations blend. For example, you can use MixBlend.Replace to replace the current animation smoothly:

             spineAnimationState.SetAnimation(0, "fullBodyAnimation", true).MixBlend = MixBlend.Replace;
      • Custom Blending Logic: Implement custom blending logic using the UpdateLocal callback method. This allows you to control the blending process more precisely. Here is an example:

             void OnUpdateLocal(ISkeletonAnimation animated)
             {
                 if (mixing)
                 {
                     otherAnimation.Animation.Apply(skeleton, 0, 1, false, null, easedTime, MixBlend.Replace, MixDirection.In);
                 }
             }
    3. Avoid Clearing Tracks: Instead of clearing tracks, use SetEmptyAnimation or blend to a new animation directly. Clearing tracks can result in abrupt transitions.

    4. Adjust Mix Durations: Fine-tune the mix durations for your transitions to ensure they are smooth. This may require some experimentation to get the desired effect.

    5. Use Full Body Animations When Necessary: If blending separate animations proves too complex or results in undesirable transitions, consider creating full body animations for certain actions. This can simplify the blending process and ensure consistency.

    By following these steps, you should be able to achieve smoother transitions between separate upper and lower body animations and full body animations in your Spine and Unity project.

    ShiosakiYuta Welcome to the Spine forum! First of all, this forum has a translate button, so feel free to post in your native language.

    If you want to make sure that mixing is clean, you can use addAnimation instead of setAnimation to wait for the previous animation to complete so that the end of the previous animation and the start of the next animation are timed together. (If the delay is set to 0 and the mix duration is set to 0.2, the mix will start 0.2 seconds before the previous animation is complete.)

    If transitions do not work well with mixing alone, it may be better to have a short animation for the transition. In fact, Spineboy has two very short transition animations: run-to-idle and idle-turn.
    By interspersing these short animations, the pose can be more reliably changed to match the next animation and look more natural.

      Misaki 返信ありがとうございます!
      今回の場合、Track1のアニメーションに対してAddAnimationを呼ぶということでしょうか。
      つなぎのアニメーションを試してみましたが、結局Track1に対してSetEmptyAnimationを呼ぶ必要があるので、そのタイミングでアニメーションが破綻してしまいました。AddEmptyAnimationでも効果は同じです。

      今回のやりたいアニメーションフローは以下になります
      Track0:全身の歩きアニメーション (setAnimation(0, "walk", true))
      Track1:None
      ↓攻撃ボタンを押す
      Track0:下半身の歩きモーション (setAnimation(0, "lower_walk", true))
      Track1:上半身の攻撃モーション (setAnimation(1, "upper_gun", true))
      ↓攻撃ボタンを離す
      Track0:全身の歩きモーション (setAnimation(0, "walk", true))
      Track1:None (setEmptyAnimation(1, 0.25f))
       このタイミングで上半身のモーションが一瞬残っている感じになります

      SampleのAnimationTesterでSpineboyを使用してSpineboyで同じことを試すと違和感がないため、モデルの作りの問題の可能性もあるでしょうか。。
      (私のプロジェクトではハイポリゴンでボーンも大量に使用しています)

      何か解決へのアプローチがあれば何でも教えて頂けると助かります。
      よろしくお願いいたします。

        ShiosakiYuta

        今回の場合、Track1のアニメーションに対してAddAnimationを呼ぶということでしょうか。

        申し訳ありませんが問題が歩行アニメーション同士のトランジションがうまくいかないということだと勘違いしておりました。

        ↓攻撃ボタンを離す
        Track0:全身の歩きモーション (setAnimation(0, "walk", true))
        Track1:None (setEmptyAnimation(1, 0.25f))
         このタイミングで上半身のモーションが一瞬残っている感じになります

        上半身のモーションを一瞬でも残したくない場合はSetEmptyAnimationのミックスデュレーションを0にしたほうが良いかと思いますが、0.25秒に設定されているのはなぜでしょうか?

        複雑なスケルトンであってもミックスに影響は出ないはずだと思いますが、トランジションアニメーションを作成してもAddEmptyAnimationを使用してもアニメーションが破綻するという状況が言葉だけで想像するのが難しいので、可能であれば問題が確認できるSpineプロジェクトをメール経由でお送りいただけますと幸いです: contact@esotericsoftware.com
        送っていただくSpineプロジェクトは、問題が分かる限り、画像をダミー画像に差し替えたり、関係ないボーンやアニメーションは全て削除した最小限のもので構いません。
        メールをお送りいただく場合はこのスレッドのURLを本文中に含めてください。データをいただき次第で何が問題なのかを確認いたします。

          Misaki
          メールにて再現可能なプロジェクトを送付いたしました。
          お手数をおかけしますが、ご確認お願いいたします。

          Misaki 上半身のモーションを一瞬でも残したくない場合はSetEmptyAnimationのミックスデュレーションを0にしたほうが良いかと思いますが、0.25秒に設定されているのはなぜでしょうか?

          こちら0にすると一瞬完全にEmptyの状態が映ってしまうため少し長めに設定していました。
          現象は添付Projectで確認していただけると幸いです。
          よろしくお願いいたします。

            • Editado

            ShiosakiYuta プロジェクトファイルを送っていただきありがとうございます!

            この問題はスケルトンにパスコンストレイントを使用していて、そしてそのターゲットパスを変形キーによって変形させて動かしていることによって起きていると思われます。
            Spineのプレビュービューでミックスした時とUnity上でミックスした時で結果が異なっているので、ランタイム側のバグの可能性があるかもしれません。
            ※後述の通りこの問題は変形キーを利用しなくても再現できることを確認しましたので、この記述は無視してください

            変形キーを多用するのはあまり推奨できない動かし方なので、ボーンを使ってパスを動かすようにアニメーションを修正することを検討したほうが良いかもしれません。

            両足のパスはボーンに対してバインドされていたのでパスがボーンに対してバインドできることはご存知かと思いますが、変形キーはアニメーションデータのサイズを増加させてしまう他、ボーンを使うよりもアニメーションの自由度や流用しやすさの点で劣ります。グラフビューにおいて変形キーの表示は0(変形なし)か100(変形あり)の2つの値しか表示されずボーンを使って動かすよりもキー間での変化の量が分かりづらく、また頂点間の補間が必ず直線的に行われるというルールにより、曲線の動きが作りづらい(より多くのキーが必要になる)という欠点があるので、ぜひボーンを使用してパスを変形する方法を検討してみてください。

            • Editado

            ShiosakiYuta この問題はについて確認する中で、変形キーはそのままでもトラック0に追加する待機アニメーションをミックスデュレーション 0 でセットすることでも解決できることを確認しました。
            (特定のアニメーションのミックスデュレーションを指定したい場合は以下のようにSetAnimation()メソッドから返されたTrackEntryオブジェクトに対して指定します)

                    TrackEntry trackentry = spineAnimationState.SetAnimation(0, waitAnimationName, true);
                    trackentry.MixDuration = 0;

            これで問題が解決するかどうかお試しいただけますと幸いです。

            混乱させてしまって申し訳ありません。この問題についてより単純なスケルトンで再現してみたところ、Spine上でのプレビューとUnity上での再生に差異はなく、また変形キーを使わなくても再現ができました。(ただ変形キーはあまり多用しないほうが良いと言うのは一般的に言えることですのでその点はご留意ください。)

            起こっている問題を分かりやすくするためにプレビュービュー上で問題を再現しました:

            上の動画で起きているのは以下の通りです:

            1. Track0 に設定したアニメーション、shake-hands では手前の腕を前に差し出しますが、Track1 にアニメーション wave-hand を設定すると手前の腕のポーズはさらに上書きされて腰に固定されます。
            2. Track1 を空にすると wave-hand が上書きしていた手前の腕のポーズが元に戻ります。Track1 を空にするのと Track0 に新しいアニメーションを設定するのを同時に行うと、Track0 にもともと入っていた shake-hands と 次のアニメーションとでミックスが発生します。

            Track0に入っていたアニメーションが Track1 のポーズに近かったり、Track1 のアニメーションから次のアニメーションのちょうど中間のポーズになっていればこのミックスは違和感なく行われますが、上の動画の例のように大きく異なるポーズになっている場合は違和感が発生する可能性があります。

            解決策としては先にご案内したように Track0 で次に再生したいアニメーションをミックスデュレーション0でセットするのが良いかと思います。
            この回答がご参考になれば幸いです。

              Misaki
              ありがとうございます!

              トラック0に追加する待機アニメーションをミックスデュレーション 0 でセットする

              こちらで完璧に動作しました!
              大変助かりました!