Finish animation

May 27, 2010 at 7:02 PM

How do I stop animations from being interrupted once started? I have a punch animation,I'd like it to play through before it can be interrupted, either by another animation, or pressing the punch button again.

May 31, 2010 at 6:26 PM
Edited May 31, 2010 at 6:28 PM

Currently, I'm using this code,

else if (keyboardState.IsKeyDown(Keys.Space) 
&& !Component.AnimationController.IsPlaying.Equals(Component.SkinnedModel.AnimationClips["Punch"]))
            {
                Component.AnimationController.PlayClip(Component.SkinnedModel.AnimationClips["Punch"]);
            }

 

 I understand this to mean that if the punch animation is not already playing, go ahead and play it. I've replaced punch with other animations, but it's the code that isn't right. My problem is twofold, 1. I need to make the punch uninterruptable 2. I need the punch to play from start to finish every time, currently, releasing the key and/or pressing it again prematurely terminates the animation.

Jun 11, 2010 at 3:50 PM

I have a boolean variable to allow animations to play.

 bool locked = false

 In order to allow a punch animation to play to completion without interruption I use this code,

 else if (keyboardState.IsKeyDown(Keys.Space) && locked == false
            { 
                Component.AnimationController.PlayClip(Component.SkinnedModel.AnimationClips["Punch"]); 
 
                while(!Component.AnimationController.HasFinished.Equals("Punch")) 
                { 
                    locked = true;  
                } 
            } 


I've tried a few different variations on this, basically, while the punch animation is playing, lock all other animations, including repeat instances of punch. When it is finished, release the lock. The logic seems sound to me, but it causes the game to freeze.
I've been stuck a while on this issue, I could really use the help

Jun 11, 2010 at 11:06 PM

I'm not sure of your complete solution, but the property types for AnimationController.HasFinished and AnimationController.IsPlaying are both boolean.  So True or False will never equal AnimationClips["Punch"] or "Punch".

In your last post, your code could look something more like the following:

else if (keyboardState.IsKeyDown(Keys.Space)

            { 

                if (locked==false) {
                   Component.AnimationController.PlayClip(Component.SkinnedModel.AnimationClips["Punch"]);
                   locked = true  
                } else if (Component.AnimationController.HasFinished) { 
                        locked = false;
                } 
            } 

You'd have to check the value of 'locked' before any clip you try to play though.  This prevents a waiting 'while' loop which can hang multi-tasking/multi-threaded systems.  Basically, you want to allow input to continue to process even though you aren't firing additional animations.

Jun 11, 2010 at 11:30 PM
Thanks, I tried your code, but it causes the Punch animation to loop endlessly. I'm wondering how to stop it after one iteration of the punch.
Jun 11, 2010 at 11:54 PM
Edited Jun 12, 2010 at 12:50 AM

Make sure the looping on the animation controller is off.  It's enabled by default.

                Component.AnimationController.LoopEnabled = false;

 

I have this logic in my player character game .Update event:

            if (!Component.AnimationController.IsPlaying)
            {
                Component.AnimationController.LoopEnabled = false;
                Component.AnimationController.StartClip(Component.SkinnedModel.AnimationClips["Idle"]);
            }

The "Idle" will loop as long as no animation is playing.  Basically it makes "Idle" the default animation.  
You could move the logic to set "locked" to false there instead leaving:
else if (keyboardState.IsKeyDown(Keys.Space)

            { 

                if (locked==false) {
                   Component.AnimationController.PlayClip(Component.SkinnedModel.AnimationClips["Punch"]);
                   locked = true  

                }

                }

and the update would have the following:

 

            if (!Component.AnimationController.IsPlaying)
            {
                Component.AnimationController.LoopEnabled = false;
                locked = false;
                Component.AnimationController.StartClip(Component.SkinnedModel.AnimationClips["Idle"]);
            }