x


Animations ignore TimeScale

Is it possible to play animations while the TimeScale is 0? I'm talking about bone animations imported from Maya. The basic scenario is that i have a bunch of rigidbodies on screen, i'd like to "pause" the screen on a button press, which plays an animation and turns timeScale to 0. But because timeScale is 0 animations won't play at all.

Is there any way of achieving this?

I've got another method where i use delegates and events to notify objects when i've entered "pause mode", but i thought that just turning the timeScale down would be more efficient than N method calls.

Thanks

//edit// One idea that i do have is that i could write an extension for the AnimationClip class for a new function to play the animation, but also pass in a flag (ignoreTimeScale), if this flag is true, then i could scrub through the animation using a while(animation.time < animation.length). Or something like that. Thoughts?

more ▼

asked Feb 15 '12 at 01:25 AM

Default117 gravatar image

Default117
331 26 29 33

(comments are locked)
10|3000 characters needed characters left

4 answers: sort newest

Works perfectly fine by creating an animation extension function to play the animation based on realtimeSinceStartup and a psuedo deltaTime.

Add the following function to a script called "AnimationExtensions.cs", and then you can simply call the function like so:

StartCoroutine( animation.Play("animName", false, () => Debug.Log("onComplete")) );

Play animation forward non timescale

    public static IEnumerator Play( this Animation animation, string clipName, bool useTimeScale, Action onComplete )
 {
 Debug.Log(&quot;Overwritten Play animation, useTimeScale? &quot; + useTimeScale);
 //We Don't want to use timeScale, so we have to animate by frame..
 if(!useTimeScale)
 {
 Debug.Log(&quot;Started this animation! ( &quot; + clipName + &quot; ) &quot;);
 AnimationState _currState = animation[clipName];
     bool isPlaying = true;
     float _startTime = 0F;
     float _progressTime = 0F;
     float _timeAtLastFrame = 0F;
     float _timeAtCurrentFrame = 0F;
     float deltaTime = 0F;


 animation.Play(clipName);

 _timeAtLastFrame = Time.realtimeSinceStartup;
         while (isPlaying) 
 {
             _timeAtCurrentFrame = Time.realtimeSinceStartup;
             deltaTime = _timeAtCurrentFrame - _timeAtLastFrame;
             _timeAtLastFrame = _timeAtCurrentFrame; 

                _progressTime += deltaTime;
                _currState.normalizedTime = _progressTime / _currState.length; 
                animation.Sample ();

 //Debug.Log(_progressTime);

                if (_progressTime >= _currState.length) 
 {
 //Debug.Log(&quot;Bam! Done animating&quot;);
 if(_currState.wrapMode != WrapMode.Loop)
 {
 //Debug.Log(&quot;Animation is not a loop anim, kill it.&quot;);
                     //_currState.enabled = false;
                     isPlaying = false;
 }
 else
 {
 //Debug.Log(&quot;Loop anim, continue.&quot;);
 _progressTime = 0.0f;
 }
                }

             yield return new WaitForEndOfFrame();
         }
         yield return null;
 if(onComplete != null)
 {
 Debug.Log(&quot;Start onComplete&quot;);
 onComplete();
 } 
 }
 else
 {
 animation.Play(clipName);
 }
 }

Play animation reverse non timescale If you would like to do the same, but reverse your animations instead, you need to reverse your logic, like so:

 public static IEnumerator ReverseNonTimeScale( this Animation animation, AnimationClip _clip, Action onComplete )
 {
 AnimationState _currState = animation[_clip.name];
     bool isPlaying = true;
     float _progressTime = 0F;
     float _timeAtLastFrame = 0F;
     float _timeAtCurrentFrame = 0F;
     float deltaTime = 0F;

 animation.clip = _clip;

 Debug.Log(animation.clip.name);

 _timeAtLastFrame = Time.realtimeSinceStartup;
    while (isPlaying) 
 {
        _timeAtCurrentFrame = Time.realtimeSinceStartup;
        deltaTime = _timeAtCurrentFrame - _timeAtLastFrame;
        _timeAtLastFrame = _timeAtCurrentFrame; 

        _progressTime += deltaTime;
        animation.Play();
        _currState.normalizedTime = 1.0f - (_progressTime / _currState.length);
 //Debug.Log(_progressTime + &quot;, &quot; + _currState.normalizedTime);
        animation.Sample();
        animation.Stop();

        if (_progressTime >= _clip.length) 
 {
         _currState.normalizedTime = 0.0f;
 isPlaying = false;
        }

        yield return new WaitForEndOfFrame();
    }
    yield return null;
 if(onComplete != null)
 {
 Debug.Log(&quot;Start onComplete&quot;);
 onComplete();
 } 
 }
more ▼

answered Feb 15 '12 at 11:37 PM

Default117 gravatar image

Default117
331 26 29 33

Is there a way to use this method with timescale = 0, but play the animation in reverse?

Aug 14 '12 at 07:30 PM Ben BearFish

Yeah you sure can, just reverse your logic. So instead of setting the normalized time to the progress divided by the clip length, you want to set it to the normalized total (1) minus the difference. So that it starts from 1 and decreases. I edited my answer with the code.

Aug 14 '12 at 11:50 PM Default117
(comments are locked)
10|3000 characters needed characters left

So I copied and pasted the c# script above and get these errors in the console. I never work with C# (only JS) and couldn't work out what the problems are.. can you help?

For the main script: /AnimationExtensions.cs(1,28): error CS0116: A namespace can only contain types and namespace declarations

[is pointing to the following line in the script: public static IEnumerator Play( this Animation animation, string clipName, bool useTimeScale, Action onComplete ) ]

TYVM

more ▼

answered Nov 14 '12 at 07:55 AM

StoneFish gravatar image

StoneFish
16 3

As far as i know (Someone please correct me if im wrong) Actions only work in C#. So you cannot call them via javascript.

Nov 14 '12 at 08:00 AM Default117

Action is part of the System.Action namespace in C#. Though I'm not familiar with JavaScript, Actions are part of the .Net library, so unless you can import it into JavaScript, I don't think you can use actions.

Nov 14 '12 at 09:31 PM Ben BearFish

guys on the Action issue. it's easy enough to "get at" Action inside javascript, thank goodness. (if you use Prime31 plugins, you do it every day)

Note my answer here, not the selected answer the "useful common trick" answer

http://answers.unity3d.com/questions/443114/writing-with-c-and-javascript-simultaneoulsy.html

essentially it's a delegate, like a Function type from U/S

if you're struggling with the use of Action here, suggest very simply delete it from the proposed code, heh!

hope it helps

@Default117 your answer here is fantastic BTW, thanks!

Apr 29 at 09:31 AM Fattie
(comments are locked)
10|3000 characters needed characters left

Might I ask how someone goes about creating a "creating an animation extension function"? Does AnimationExtensions have to be its own public static class? Or is there another method to do this? Thanks.

more ▼

answered Mar 22 '12 at 03:48 AM

AbsurdHart gravatar image

AbsurdHart
1 1 1 2

Correct

public static class AnimationExtensions {

//Play an animation from a string parameter and run an oncomplete
public static IEnumerator YourFunctionName( this Animation anim , string clipName, Action onComplete )
{

}

}

Mar 22 '12 at 03:50 AM Default117

Ahh, I see now. You can overload the Unity Animation Play function. I learn something everyday. What would be the equivalent of overloading for particles to get them to emit/animate as well? Thanks.

Mar 22 '12 at 08:07 PM AbsurdHart
(comments are locked)
10|3000 characters needed characters left

I pretty much did it the way you said in your edit. Base it off the timed components from the animation, and create a coroutine that I kept track of in my own List and based other functions that coincided with it off of Time.realtimeSinceStartup. This was just a helper timer to base coroutines off of since coroutine yielding is also derived form timeScale.

more ▼

answered Feb 15 '12 at 07:34 PM

dannyskim gravatar image

dannyskim
3.9k 5 7 19

Thanks for the confirmation! I'll implement this method now, and see how i go.

Feb 15 '12 at 10:30 PM Default117

Does anyone know is there an equivalent way to do this, but with Emitting Particles instead of playing Animations and if so how? Thanks.

Mar 22 '12 at 04:51 AM AbsurdHart
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x460
x261
x221
x83

asked: Feb 15 '12 at 01:25 AM

Seen: 2107 times

Last Updated: Apr 29 at 09:31 AM