So I have a turn based game with a move animation and an attack animation. the order these play in are move forward animations > skill animation > move backwards animation. The move forward and backward animations have events at the point in the animation to start the translation for the character and the attack animation has an event for when the actual hit of the animation is done so I can do damage animations as needed. The problem I'm having is the start moving move events and the hit events are being called twice when they are being fired. The animations are not set to loop. I initialise the script and set the character animations to idle at the beginning of the scene. I use the following SetAnimations method to do any animation setting as follows:
public void SetAnimation(string animation, bool loop, float timeScale = 1f)
{
if (!animation.Equals(currentState))
{
previousState = currentState;
Spine.TrackEntry animationEntry = SkeletonAnimation.state.SetAnimation(0, animation, loop);
currentAnimationDuration = SkeletonAnimation.state.GetCurrent(0).Animation.Duration;
animationEntry.TimeScale = timeScale;
if (currentSkill != null)
{
animationEntry.Event -= currentSkill.OnSkillApplication;
animationEntry.Event += currentSkill.OnSkillApplication;
}
if (movingAnimation == true)
{
animationEntry.Event -= OnMove;
animationEntry.Event += OnMove;
movingAnimation = false;
}
currentState = animation;
if (currentState != "idle")
{
animationEntry.Complete -= AnimationEntryComplete;
animationEntry.Complete += AnimationEntryComplete;
}
}
}
This is the code for sliding the character based on the OnMove event
private void OnMove(Spine.TrackEntry trackEntry, Spine.Event e)
{
if (e.Data.Name == "Start_Moving_Forward" || e.Data.Name == "Start_Moving_Backward")
StartCoroutine(LerpMovement(_distance, _destination));
}
private IEnumerator LerpMovement(Single distance, Vector3 destination)
{
float speed = distance / (currentAnimationDuration);
while (Vector3.Distance(destination, transform.position) >= 0.05f)
{
transform.position = Vector3.MoveTowards(transform.position, destination, speed * Time.deltaTime);
yield return null;
}
GridUnit.transform.gameObject.transform.position = destination;
Debug.Log("Move");
yield return new WaitForSecondsRealtime(0.5f);
}
This is the an example code for the OnSkillApplication event to apply damage and what not in the skill class
public override void OnSkillApplication(Spine.TrackEntry trackEntry, Spine.Event e)
{
if (e.Data.Name == "Hit")
{
OnHit(Targets);
}
}
public void OnHit(List<ITargetUnit> targets)
{
Debug.Log("Event Fired");
double damage = SkillStats.Attack * Caster.Stats.Attack;
ApplyDamage(targets, damage);
}
This is also the method which gets called to carry out skill functions
public void SetSkillAnimation(ActiveSkill skill)
{
StartCoroutine(PlaySkillAnimation(skill));
}
public IEnumerator PlaySkillAnimation(ActiveSkill skill)
{
currentSkill = skill;
bool needMovement = skill.NeedMovement;
Vector3 previousPosition = GridUnit.transform.position;
if(needMovement)
{
var target = (IGridUnit)skill.Targets[0];
var targetPosition = target.transform.position + GetOffSet();
yield return StartCoroutine(MoveToTarget(targetPosition));
}
currentSkill = skill;
SetAnimation(skill.Name.ToLower(), false);
yield return new WaitForSecondsRealtime(currentAnimationDuration + 0.5f);
if(needMovement)
{
yield return StartCoroutine(MoveToTarget(previousPosition));
}
}
Note that at the end of SetAnimation im calling the Complete built in event in spine, i checked to see if this was also being called twice but it is working as intended and only being called once. Attached is a picture of my console showing the debug in the methods being fired twice as well. The event fired debug is for the Hit event. I have been clawing at this for an embarrassingly long time but im very new to using spine and have come to the forums for some guidance on what could be the issue.