- Изменено
Events Playing twice in code
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.
Typically the issue when events are playing twice is that the event callback method has accidentally been registered twice. Nevertheless in your code I could not spot any obvious mistake. Could you please check if your event methods are indeed registered only once, and if that is the case send us a minimal Unity project that still demonstrates your issue? You can send it as a zip package to contact@esotericsoftware.com, briefly mentioning this forum thread URL so that we know the context. Then we can have a look at what's going wrong here.
Update in case anyone has this issue. I did a fresh re-install of spine in unity and the events stopped firing twice without having to change any code.
Thanks for getting back to us. Even though that's very strange behaviour, we're glad it was resolved by re-installing.
Whenever Unity starts to behave strangely (e.g. listing dependency related compile errors for no obvious reason), as a first step it may often be sufficient to delete the Library
directory in your Unity project, which forces everything to be recompiled.