• RuntimesUnityBugs
  • Unityで加算トラックを使用したアニメが正常に描画されません。

  • Đã chỉnh sửa

Problem statement

Unity上で加算トラックを使用したアニメが正常に描画されません。

剣の柄を引っ張られている剣士のアニメ「GrabbedSword」があります。
動きを追加した「GrabbedSword_add」アニメをTrack1で加算描画します。
Spineエディタ上では問題なくミックス描画されました。
これをUnityに実装しました。

すると上の動画のように赤いパーツが拡大され続けて画面を覆い尽くしてしまいます。
調べてみるとこれはキャラクターの口のパーツでした。
キャラクターの口のパーツは加算トラックでスケールを縮小しています。


試しに口のスケール縮小キーだけを消した「GrabbedSword_add2」を作成し、同様の条件でアニメを再生したスケルトンはパーツの拡大は起こりませんでした。
スケールを調整したアニメを加算トラックで再生する際に何らかの不具合が起こっているように見えます。

public class TestAnim : MonoBehaviour
{
    public SkeletonAnimation skeletonAnimation; 
    [HideInInspector] public TrackEntry trackEntry0;     // Main
    [HideInInspector] public TrackEntry trackEntry1;     // Blend.Add
    void Start()
    {
        skeletonAnimation = GetComponent<SkeletonAnimation>();
        trackEntry0 = skeletonAnimation.AnimationState.SetAnimation(0, "Test/GrabbedSword", true);
        trackEntry1 = skeletonAnimation.AnimationState.AddAnimation(1, "Test/GrabbedSword_add", true, 0f); 
        trackEntry1.MixBlend = MixBlend.Add;
    }
}

コードはこのように記述しました。

・Spineのバージョン:4.2.33
・ランタイム:2024_7_30の最新版
・Unityのバージョン:2022_3.13f1

こちらの現象が再現するプロジェクトをメールでお送りさせて頂きました。
ご確認いただけますと幸いです

  • Misaki đã trả lời bài viết này.
    Related Discussions
    ...

    koyu2 こんにちは、お送りいただいたプロジェクトを確認しましたが、これはバグではなくMixBlendの値がaddになっている場合の予期された動作だと思われます。
    APIリファレンスに記載されているaddの説明は以下の通りです:
    https://esotericsoftware.com/spine-api-reference#MixBlend

    Transitions from the current value to the current value plus the timeline value. No change is made before the first frame (the current value is kept until the first frame).
    add is intended for animations layered on top of others, not for the first animations applied. Properties set by additive animations must be set manually or by another animation before applying the additive animations, else the property values will increase each time the additive animations are applied.

    注目していただきたいのが一番最後の説明文です。ここで、「加算アニメーションによって設定されるプロパティは、加算アニメーションを適用する前に手動で設定するか、別のアニメーションによって設定する必要があります。そうしないと、加算アニメーションが適用されるたびにプロパティ値が増加します。」と説明されている通り、ご報告いただいた問題で発生しているのは下位トラックのアニメーションでは設定されていないプロパティ(スケール)に対して上位トラックでスケールのアニメーションが設定されているためにアニメーションが適用されるたびにプロパティ値が増加していると思われます。

    実際、トラック0で再生されているGrabbedSwordアニメーションにmouth-ボーンのスケールX/Y 1.0のキーを追加したところこの問題は解消することを確認しました。
    加算するアニメーションで使用するプロパティが下位トラックでも設定されていることを確認してみてください。


    また、問題とは直接関係はありませんが、今回お送りいただいたUnityプロジェクトにも不要なファイルが含まれていましたので、もし今後問題再現用のプロジェクトをお送りいただく場合には以下のフォルダやファイルも削除していただけますと幸いです。

    ■ 不要なフォルダ
    /obj
    /Logs
    /UserSettings
    
    Assetsフォルダ内のSpine Examplesフォルダも不要なので削除できます。
    
    ■ 不要なファイル
    拡張子が.csproj、slnとなっているファイル
    UpgradeLog.htm

    加えて、ファイル名に全角文字が使用されていることが原因でSkeletonAtlasAssetやSkeletonDataAssetなどでファイル参照エラーが発生していたため、可能な限り英字で命名いただけますと幸いです。

    スムーズな問題確認のためにご協力をお願いいたします。

    こんにちは美咲さん!
    お返事ありがとうございます。

    実際、トラック0で再生されているGrabbedSwordアニメーションにmouth-ボーンのスケールX/Y 1.0のキーを追加したところこの問題は解消することを確認しました。
    加算するアニメーションで使用するプロパティが下位トラックでも設定されていることを確認してみてください。

    こちらの環境で同様にトラック0にスケールキーを追加してみたのですが、残念ながら問題は解決されませんでした。原因の切り分けに星画像1つの最小限構成でも試してみたのですが、変わらずUnity上で画像が拡大し続けてしまいます。

    track0アニメでは星が左右に動き、スケール1.0のキーが存在します。
    track1_Add_Scaleでは星が上下に動き、スケール縮小キーが存在します。
    左上のプレビューは加算トラックを適用した状態です。
    これをバイナリ形式でエクスポート後、アタッチしたスクリプトのStart()で下記の処理を1回のみ行いました

    trackEntry0 = skeletonAnimation.AnimationState.SetAnimation(0, "track0", true);
    trackEntry1 = skeletonAnimation.AnimationState.AddAnimation(1, "track1_Add_Scale", false, 0f);
    trackEntry1.MixBlend = MixBlend.Add;

    このように星が急速に拡大します。

    お手数をおかけしますが、もう一度見て頂けないでしょうか?
    2バイト文字とLibrary以外の不要ファイルについても承知しました。
    問題が再現するプロジェクトをUnityとSpine両方をお送り致しますので、何卒ご査収頂けましたら幸いです。

    • Misaki đã trả lời bài viết này.

      koyu2 最小限の再現プロジェクトをお送りいただきありがとうございます!

      問題の原因はエクスポート設定でアニメーションクリーンアップのチェックが入っていることです。
      アニメーションtrack0で記録されているスケールX/Yのキーは1.0でセットアップポーズと同じなので、この場合はアニメーションクリーンアップでキーが消えてしまいます。
      試しにUnityプロジェクト内に含まれているエクスポートデータTEST_TrackAdd.skel.bytesをSpineにインポートしたところ、アニメーションtrack0にはスケールのキーがありませんでした。

      アニメーションクリーンアップのチェックを外してエクスポートしたスケルトンデータを使用した場合にはUnity上でもアニメーションが正常に再生できることを確認しましたので、これで問題が解決するかどうかご確認いただけますと幸いです。

      • koyu2 đã thích điều này.

      ご査収ありがとうございます!
      クリーンアップでセットアップポーズのキーが消えるのは盲点でした。
      ご提示頂いたエクスポート時のクリーンアップ設定を外すことでパーツの拡大問題が無事に解消されました!
      クリーンアップは他のアニメで使用しているので、予めtrack0のアニメのスケールを1.001のように微妙に変えておくなどの方法も合わせて対応していきたいと思います。

      仕様の範囲内とのことでお騒がせしました。
      諸々サポートくださり感謝致します!

      • Đã chỉnh sửa

      すみません、上記MixBlendについてもう一つ質問です。
      下位トラックにキーがない状態で上位トラックでキーが存在するアニメを加算再生した場合、描画が崩れてしまいますが、Unityランタイムのコードでこれを初期化する手段はありますでしょうか?


      例えば「track0」アニメにキーが存在しないボーンを回転する「track1_Add2」アニメを加算再生した場合、下の動画のように値が増加し続け高速回転をします。
      ゲーム中にこの状態になったとしても、Track1のアニメをSetAnimationEmptyなどで上書きすれば値が増加し続ける加算アニメは無くなり、元のtrack0のアニメに戻るのではないかと考えました。

      しかし、動画のように水平移動する元々のtrack0アニメには戻らず、
      track1で変化した回転の値が残っているため角度のついた移動になってしまいます。

      ーーーーー

          {
              if (Input.GetKeyDown(KeyCode.Alpha2))
              {
                  trackEntry1 = skeletonAnimation.AnimationState.AddAnimation(1, "track1_Add2", true,0f);
                  trackEntry1.MixBlend = MixBlend.Add;
                  Debug.Log("<color=yellow> ★Track加算テスト2</color>");
              }
              if (Input.GetKeyDown(KeyCode.Alpha3))
              {
                  skeletonAnimation.AnimationState.ClearTracks();
                  trackEntry0 = skeletonAnimation.AnimationState.SetEmptyAnimation(0, 0f);
                  trackEntry1 = skeletonAnimation.AnimationState.SetEmptyAnimation(1, 0f);
                  trackEntry1.MixBlend = MixBlend.Replace;
                  trackEntry0 = skeletonAnimation.AnimationState.SetAnimation(0, "track0", true);
                  skeletonAnimation.AnimationState.Apply(skeletonAnimation.Skeleton);
                  Debug.Log("<color=yellow> ★Track初期化テスト</color>");
              }
          } 

      ーーーーー
      このようにSetEmptyAnimationを適用したり、MixBlendをReplaceに置き換えてみたり、ClearTrack()を使用してみたりしたのですが、どうにも上手くいきません。
      ゲーム中、元のtrack0のアニメに正常に戻す方法はありますか?

      • Misaki đã trả lời bài viết này.

        koyu2 もし単純にスケルトンの全てのプロパティをセットアップポーズにリセットするので良いのでしたらSkeleton setToSetupPose を利用できます。ただ下位トラックのアニメーションを途切れさせずにリセットしたい場合、このメソッドはスケルトン全体に影響するので一瞬セットアップポーズに戻ったのが見える可能性があります。
        特定のボーンのトランスフォームだけリセットしたい場合は Bone setToSetupPose メソッドを利用できます。

        • koyu2 đã trả lời bài viết này.
        • koyu2 đã thích điều này.

          Misaki
          お返事ありがとうございます。
          track0のアニメを変更する際にSetAnimationをしていたので、直前にSkeleton setToSetupPose を挟むことで初期化ができました。
          ご助言に感謝します!

            koyu2 無事初期化できたとのことで良かったです!また何か不明な点がありましたらお気軽にこのフォーラムでご質問ください。
            今後ともSpineをよろしくお願いいたします。

            • koyu2 đã thích điều này.