• Unity
  • skeletonAnimation.AnimationName with setAnimation()

Is it possible to mix these two in Unity?

I'm using

skeletonAnimation.AnimationName

to set my animations and all is working as expected. The problem occurs when I want to add another track using

skeletonAnimation.AnimationState.SetAnimation(1,fallName,false)

For some reason it fails to override the key frames on the first track. Is this because it is not possible to mix these two bits of code with Spine?

Any insight would be super helpful.

Thanks in advance!

Related Discussions
...
  • 編集済み

That should work fine. The SkeletonAnimation.AnimationName property only sets track 0 of the AnimationState.

It could have something to do with your animations or some changes to AnimationState.

We may need your project to test. If you want, you can send it to unity@esotericsoftware.com

That's what I had seen from looking at the source code. I thought it was very strange indeed. I even tried replacing all of my

SkeletonAnimation.AnimationName

lines with the

setAnimation(0

, equivalent and things seemed to bonk out on me.

What exactly should I send to unity@esotericsoftware.com? A test scene demoing the problem?

Thanks in advance!

You can send just the skeleton exports. (json, atlas.txt, png) and post your code here.

Or just a test scene. Either one should work.

Ok sounds great i'll send the files right over.
My spine runtime verstion.txt contains this

This Spine-Unity runtime works with data exported from Spine Editor version: 3.5.xx

The script that handles the animations contains the following code.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Spine.Unity;
using Spine;
using StudioName.Utility;

public class CharacterAnimatorController : MonoBehaviour {

   public enum AnimationType { Spine, Mecanim }
   [TooltipAttribute("The type of animator we want to animate the character with")]
   public AnimationType animType;
   public Animator animator;
   [HeaderAttribute("Spine Animation Properties")]
   public SkeletonAnimation skeletonAnimation;   
[SpineAnimation(dataField: "skeletonAnimation")] public string idleName = ""; [SpineAnimation(dataField: "skeletonAnimation")] public string runName = ""; [SpineAnimation(dataField: "skeletonAnimation")] public string jumpName = ""; [SpineAnimation(dataField: "skeletonAnimation")] public string quickJumpName = ""; [SpineAnimation(dataField: "skeletonAnimation")] public string tauntJumpName = ""; [SpineAnimation(dataField: "skeletonAnimation")] public string landName = "";
[SpineAnimation(dataField: "skeletonAnimation")] public string fallingName = ""; [Range(1,2)] public float runAnimationScale = 1.2f; [RangeAttribute(0,1.5f)] public float stdJumpThreshold = 0; private JumpController jumpController; private PlayerController playerController; private new Rigidbody2D rigidbody2D; private SkeletonData skeletonData; private Spine.Animation landAnimation; private Vector2 lastVelocity; private bool facingRight = true; private bool lastGrounded = true; private bool landing = false; private float quickJumpTimer = 0; void Start(){ jumpController = GetComponent<JumpController>(); playerController = GetComponent<PlayerController>(); rigidbody2D = GetComponent<Rigidbody2D>(); skeletonData = skeletonAnimation.skeletonDataAsset.GetSkeletonData(false); landAnimation = skeletonData.FindAnimation(landName); skeletonAnimation.state.Start += SpineStartHandler; skeletonAnimation.state.End += SpineEndHandler; } void OnDisable(){ skeletonAnimation.state.Start -= SpineStartHandler; skeletonAnimation.state.End -= SpineEndHandler; } // Update is called once per frame void Update () { switch(animType){ case AnimationType.Mecanim: //flips animations when facing left or right if (playerController.MovingDirection > 0 && !facingRight){ Flip(); }else if (playerController.MovingDirection < 0 && facingRight){ Flip(); } //computes a random jump when the player is grounded if(jumpController.IsGrounded){ animator.SetInteger("Random Jump", Random.Range(0,4)); } SetMecanimMovementVariables(); break; case AnimationType.Spine: //flips animations when facing left or right if (playerController.MovingDirection > 0 && !facingRight){ facingRight = !facingRight; skeletonAnimation.skeleton.flipX = false; }else if (playerController.MovingDirection < 0 && facingRight){ facingRight = !facingRight; skeletonAnimation.skeleton.flipX = true; } //if we are grounded and moving change to run animation otherwise idle if(jumpController.IsGrounded){ skeletonAnimation.loop = true; //add to our quickJumpTimer quickJumpTimer += Time.deltaTime; //if we just hit the ground play our land animation until it finishes if(!lastGrounded){ skeletonAnimation.loop = false; skeletonAnimation.AnimationName = landName; landing = true; quickJumpTimer = 0; StartCoroutine(GenUtil.Wait(Land, landAnimation.Duration)); } //ensure that we let our land animation finish before we play another animation if(!landing){ //if we aren't moving idle otherwise run animation if(Mathf.Abs(playerController.MovingDirection) > 0.01f){ skeletonAnimation.AnimationName = runName; }else{ skeletonAnimation.AnimationName = idleName; } } //if we are not grounded and we have a up velocity jump otherwise fall }else{ skeletonAnimation.loop = false; if(rigidbody2D.velocity.y > 0){ switch(jumpController.FingerCountOnJump){ //One finger case 1: //quick jump if(quickJumpTimer <= stdJumpThreshold ){ Debug.Log("Time!" + quickJumpTimer + "stdJumpThreshold" + stdJumpThreshold); skeletonAnimation.AnimationName = quickJumpName; //normal jump }else{ skeletonAnimation.AnimationName = jumpName; } break; //Two fingers case 2: skeletonAnimation.AnimationName = tauntJumpName; break; default: goto case 1; } }else{ skeletonAnimation.AnimationName = fallingName; //===This is the bit that doesn't seem to work. I also tried just state, rather then AnimationState //skeleteonAnimation.AnimationState.setAnimation(0,fallingName,false); } } break; } lastGrounded = jumpController.IsGrounded; lastVelocity = rigidbody2D.velocity; } //flips animations when the player is facing other direction private void Flip() { facingRight = !facingRight; Vector3 theScale = transform.localScale; theScale.x *= -1; transform.localScale = theScale; } private void SetMecanimMovementVariables(){ animator.SetFloat("vSpeed", rigidbody2D.velocity.y); animator.SetFloat("Speed", Mathf.Abs(playerController.MovingDirection)); animator.SetBool("Ground", jumpController.IsGrounded); } /// <summary> /// Resets the landing variable and looping of the spine animator so that other aniamtions can play /// when the landing animation is finished /// </summary> private void Land(){ landing = false; skeletonAnimation.loop = true; } /// <summary> /// Executes code when a spine animation starts /// </summary> /// <param name="trackEntry">the track entry that is currently playing (set of animations)</param> private void SpineStartHandler(TrackEntry trackEntry){ string animation = trackEntry.animation.name; if(animation == runName){ skeletonAnimation.timeScale = runAnimationScale; } } /// <summary> /// Executes code when a spine animation ends /// </summary> /// <param name="trackEntry">the track entry that is currently playing (set of animations)</param> private void SpineEndHandler(TrackEntry trackEntry){ string animation = trackEntry.animation.name; if(animation == runName){ skeletonAnimation.timeScale = 1f; } } public bool FacingRight { get { return facingRight; } }
}
4日 後

So what two animations are supposed to be playing and on which tracks to show the problem?

Run on 0 and Blink on 1 seems to work fine.

Sorry about that I messed up my code a little bit.

The falling animation is suppose to play on track 1.

//===This is the bit that doesn't seem to work. I also tried just state, rather then AnimationState
skeleteonAnimation.AnimationState.setAnimation(1,fallingName,false);

The code you sent is actually unusuable. It relies on a lot of external classes and code.
Can you just list 1) what two animations need to be played on which tracks?
2) What's supposed to happen and 3) show what actually happens? (clarify what you mean by "doesn't work")

This reminds me a lot of why I hate mechanim. I resorted to just using SetAnimation() for setting all of my animation states and it worked much more cleanly. I wonder if there's a conflict here.