Hi all,
I wish to ‘do something’ after an animation ends and so have:
IEnumerator do_sword_swipe_then_end()
{
animationTarget.animation.Blend("up_sword_action",1.0f,0.0f);
yield return new WaitForSeconds(animationTarget.animation["up_sword_action"].length);
cam.sword_action = CameraRelativeControl.SwordAction.none;
}
This is fine.
But to call this I do:
if (cam.sword_action == CameraRelativeControl.SwordAction.swipe)
{
animationTarget.animation.CrossFade("up_sword",0.1f);
StartCoroutine(do_sword_swipe_then_end());
return;
}
cam.sword_action will be true for multiple frames. I assume this is all incorrect i.e. I am starting multiple coroutines’s.
Is that correct?
If so what’s the best approach to do the animation and start the coroutine just once?
I’ve think I’ve messed up my understanding hence the issues 
Cheers
Ok, been playing still no joy.
Essentially I just want an animation to occur; then once ended continue, so…
animationTarget.animation.Blend("dig",1.0f,0.0f);
if (!do_dig_anim)
{
StartCoroutine(do_dig_then_end());
print("HERE");
}
IEnumerator do_dig_then_end()
{
print("once");
do_dig_anim = true;
yield return new WaitForSeconds(animationTarget.animation["dig"].length);
do_dig_anim = false;
shovel.state = Shovel.states.not_active;
player.state = PlayerActions.status.idle;
print("ended"+player.state);
}
I can’t see what’s wrong with this…
Any help appreciated
Cheers
If you want to wait for the coroutine to end before continuing then you need to yield it. (Just as you do with WaitForSeconds)
Your close, Your state is not visible in your code. Here is it tweaked up some.
boolean do_dig_anim = false;
void Update(){
if (Input.GetKeyDown(Keycode.X) !do_dig_anim){
StartCoroutine(do_dig_then_end());
print("HERE");
}
}
IEnumerator do_dig_then_end(){
print("once");
do_dig_anim = true;
animationTarget.animation.Crossfade("dig",0.2f);
shovel.state = Shovel.states.active;
player.state = PlayerActions.status.digging;
yield return new WaitForSeconds(animationTarget.animation["dig"].length);
do_dig_anim = false;
shovel.state = Shovel.states.not_active;
player.state = PlayerActions.status.idle;
print("ended"+player.state);
}
When you use StartCoroutine, it starts the process, then immediately skips to the next line of code (the waiting part only happens within the actual coroutine). If you want the print(“here”) bit to only occur after the do_dig_then_end has completed, you have do this:
yield return StartCoroutine(do_dig_then_end())
Sorry, missed it:
if (player.state == PlayerActions.status.digging)
{
if (!do_dig_anim)
{
StartCoroutine(do_dig_then_end());
print("HERE");
}
return;
}
This is where it goes wrong. I would expect state to be reset to not_active after the yield but it doesn't seem to be.
Cheers
@Nomad72 I’m in an update routine so can’t do that
try moving the initial state changes to the update, just in case something stupid happens like the coroutine not going off until the next frame.
boolean do_dig_anim = false;
void Update(){
if (player.state == PlayerActions.status.digging)
{
if (!do_dig_anim)
{
do_dig_anim = true;
animationTarget.animation.Crossfade("dig",0.2f);
shovel.state = Shovel.states.active;
StartCoroutine(do_dig_then_end());
print("HERE");
}
return;
}
}
IEnumerator do_dig_then_end(){
print("once");
yield return new WaitForSeconds(animationTarget.animation["dig"].length);
do_dig_anim = false;
shovel.state = Shovel.states.not_active;
player.state = PlayerActions.status.idle;
print("ended "+player.state);
}
Hmmm, yes tried that already
, still no joy.
Going to look into animation events as it would seem much more reliable and simple.
Cheers