1. 程式人生 > 其它 >特殊方式實現Spine 根運動變換 implement root motion in special way

特殊方式實現Spine 根運動變換 implement root motion in special way

技術標籤:vuejson

Environment

Unity2019.4.0f, Spine runtime for unity 3.8 目前最新的3.8版本執行時的SkeletonAnimation和SkeletonMeccanim元件下都有apply root motion的選項,勾選後就會自動附加對應元件 import latest unitypackage, add SkeletonMacenim component, check apply root motion in Animator component.

Environment

Unity2018.4.1f, Spine runtime for unity 3.7

Steps

  • open Spine/Runtime/spine-csharp/Bone.cs, and modify like below
/// <summary>Computes the world transform using the parent bone and the specified local transform.</summary>
public void UpdateWorldTransform (float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY) {
  ax = x;
  ay = y;
  arotation = rotation;
  ascaleX = scaleX;
  ascaleY = scaleY;
  ashearX = shearX;
  ashearY = shearY;
  appliedValid = true;
  Skeleton skeleton = this.skeleton;

  Bone parent = this.parent;
  if (parent == null) { // Root bone.
    float rotationY = rotation + 90 + shearY, sx = skeleton.scaleX, sy = skeleton.scaleY;
    a = MathUtils.CosDeg(rotation + shearX) * scaleX * sx;
    b = MathUtils.CosDeg(rotationY) * scaleY * sy;
    c = MathUtils.SinDeg(rotation + shearX) * scaleX * sx;
    d = MathUtils.SinDeg(rotationY) * scaleY * sy;
    worldX = 0f;
    worldY = 0f;
    //worldX = x * sx + skeleton.x;
    //worldY = y * sy + skeleton.y;
    return;
  }
  • be sure skeletonData is auto generate with .atlas.txt, .png and .json(not .skel.bytes)

  • drag the skeletonData to Hierarchy and choose "SkeletonMecanim", then a "Unity Animator Controller" will be created where skeletonData is in, and a gameObject named "Spine Mecanim GameObject (dog)" is created in Hierarchy

Sprite.png

  • select the skeletonData, click the gear icon and choose "Skeleton Baking"

    Sprite.png
  • in the bake window, check "Bake Animations", and click "Bake Skeleton" button

Sprite.png

  • a new folder named "Baked" will be created, which contains a prefab and a "Unity Animator Controller" (if your skeletonData is generate by .skel.bytes but .json, the animation baked will lose the event info and Position info, and you can't continue the steps later)

  • open animation window, then select animation named "Attack" in animator controller in baked folder, use your mouse to select all frames in bone "root", then copy by ctrl + c

Sprite.png

  • back to parent folder named "Dog2", double click animator controller to open animator window, drag animation "Attack" to any layer

Sprite.png

  • select gameObject named "Spine Mecanim GameObject (dog)" in Hierarchy, in animation window you will see animation "Attack" is list(if you finish previous step successfully), and select it.

Sprite.png

  • click "Add Property" button and choose Transform Position

Sprite.png

  • use your mouse to select all frames in Position, then paste by ctrl + v

Sprite.png

  • don't forget to save this animation by ctrl + s !

  • to enable root motion, you should check apply root motion in component Animator of gameObject "Spine Mecanim GameObject (dog)"(if unchecked, hint "Root position or rotation are controlled by curves" will appear below Apply Root Motion in component Animator, and you can't modify position or rotation of this gameObject)

Sprite.png

  • enjoy it!

By the way

  • to flip, you should use Transform.scale instead of Skeleton.ScaleX, or root motion will always move towards same direction.
  • if you translate an animation which move bone root every frame(and move 5 units in x axis totally in these frames) with another animation which stay in zero by 0.2 second, the 5 units root movement in transition(0.2 second) will blend to 0 units, so a 5 units root movement animation translate to 0 unit root movement animation result less than 5 units root movement. 由於Unity Mecanim的動畫過渡機制,本應共計在x軸上位移5單位的動畫轉移到原地不動的動畫後,最終造成的位移會小於5
  • if you want to avoid this situation, you can set Transition Duration to 0, or make the animation with root movement not move in last a few frames to fit any other animation. 為避免這種情況,可以將所有Transition Duration設為0,即不採用自動過渡而是自己提供動畫間的過渡動畫,另一種方案是每個帶有根骨骼運動的動畫都在最後幾幀不移動,用於與其他任何動畫過渡