justinallers

Using the latest version of Spine-unity-4.0-2021-09-17 Unity Runtime in a project in Unity 2021.1.15f1 I have the following error happen when leaving the project in game mode:
StackOverflowException: The requested operation caused a stack overflow.
Spine.AnimationState.QueueEvents (Spine.TrackEntry entry, System.Single animationTime) (at Assets/Spine/Runtime/spine-csharp/AnimationState.cs:564)
Spine.AnimationState.ApplyMixingFrom (Spine.TrackEntry to, Spine.Skeleton skeleton, Spine.MixBlend blend) (at Assets/Spine/Runtime/spine-csharp/AnimationState.cs:429)
Spine.AnimationState.ApplyMixingFrom (Spine.TrackEntry to, Spine.Skeleton skeleton, Spine.MixBlend blend) (at Assets/Spine/Runtime/spine-csharp/AnimationState.cs:349)
Please let me know if I have something that could be causing the StackOverflowException.
My Code being run on the player character is below:
This is currently a WIP Script to control Animation of the player character.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Spine.Unity;

public class SpineAnimator : MonoBehaviour
{
public SkeletonAnimation skeletonAnimation;
public AnimationReferenceAsset idle, run, jump, fall, dash, ledgegrab, rangeDown, rangeDownAngle, rangeStraight, rangeUpAngle, rangeUp;
public string currentAnimation0;
public string currentAnimation1;
//Values set for animations
public bool isMorphBall;
public bool isOnGround;
public float xVelocity;
public bool isFacingRight;
public bool rangeHeld;

public bool isWallGrab;
public bool isHanging;
public bool isJumping;
public bool isDashing;
public float yVelocity;


public enum AimingDirection
{
Up,
UpDiag,
Straight,
DownDiag,
Down,
Clear
}
public AimingDirection Aiming; //Direction player is Aiming





// Start is called before the first frame update
void Start()
{
Aiming = AimingDirection.Straight;
}

// Update is called once per frame
void Update()
{

if (isOnGround && xVelocity > 0)
{
SetAnimation(run, true,1, 0);
}
else if(isOnGround && xVelocity == 0)
{
SetAnimation(idle, true,1, 0);
}

if (!isOnGround)
{
if(yVelocity > 0)
{
SetAnimation(jump, false, 1, 0);
}
else if(yVelocity < 0)
{
SetAnimation(fall, false, 1, 0);
}
}

switch (Aiming)
{
case AimingDirection.Up:
SetAnimation(rangeUp, false, 1, 1);
break;
case AimingDirection.UpDiag:
SetAnimation(rangeUpAngle, false, 1, 1);
break;
case AimingDirection.Straight:
SetAnimation(rangeStraight, false, 1, 1);
break;
case AimingDirection.DownDiag:
SetAnimation(rangeDownAngle, false, 1, 1);
break;
case AimingDirection.Down:
SetAnimation(rangeDown, false, 1, 1);
break;
case AimingDirection.Clear:
skeletonAnimation.state.AddEmptyAnimation(1,0.2f,0);
break;
}

}

public void SetAnimation(AnimationReferenceAsset animation, bool loop, float timeScale, int track)
{
if (track == 0 && animation.name.Equals(currentAnimation0))
{
return;
}
else if (track == 1 && animation.name.Equals(currentAnimation1))
{
return;
}
else if (track == 0)
{
currentAnimation0 = animation.name;
}else if (track == 1)
{
currentAnimation1 = animation.name;
}
skeletonAnimation.state.SetAnimation(track, animation, loop).TimeScale = timeScale;

}


}
justinallers
  • 記事: 6

Nate

You don't want to call SetAnimation, AddAnimation, AddEmptyAnimation, etc every frame. That sets or queues a new animation. If you have a mixDuration, the old animation is mixing out so doesn't go away immediately, but you keep setting more and more animations.

You only want to call those when the animation changes. You could keep your logic and use a function that only sets a new animation if the current animation is not the right one, something like this:
https://github.com/EsotericSoftware/spine-superspineboy/blob/master/src/com/esotericsoftware/spine/superspineboy/CharacterView.java#L51-L64
アバター
Nate

Nate
  • 記事: 11351

justinallers

Thanks! I realized with this I need to do more reading of the API documentation.

I believe I found the code causing the overflow:
case AimingDirection.Clear:
skeletonAnimation.state.AddEmptyAnimation(1,0.2f,0);
break;
I have updated it as follows:
case AimingDirection.Clear:
if (skeletonAnimation.state.GetCurrent(1) != null)
{
skeletonAnimation.state.ClearTrack(1);
}
break;
justinallers
  • 記事: 6

Nate

Note AnimationState clearTrack will leave the skeleton in whatever pose it is in, while setting an empty animation will reset the keyed values back to the setup pose.
アバター
Nate

Nate
  • 記事: 11351


Return to Unity