Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by Macro · Jan 29, 2014 at 11:01 PM · animatormecanimanimator controller

Get length of animator state/transition?

There seems to have been a few queries around this area, such as:

http://forum.unity3d.com/threads/162505-Get-animation-length-in-Mecanim http://answers.unity3d.com/questions/444696/animation-length-mecanim.html

However there seems to be no answers as of yet. The problem I have is that I want to change from the state "walking" to "punch" however I need to check for button presses to see if I need to then go to "punch-2" or back to "idle".

So simplest way to achieve this seems to be change the animation, then find out how long is left in the animation, and give that as the period to listen for button presses, however it seems like the animation info Length property is not accurate, so is there some preferred method or best practice around doing this?

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image aeroson · Jan 30, 2014 at 01:55 AM 0
Share

You can use animation events ins$$anonymous$$d. http://docs.unity3d.com/Documentation/Components/animeditor-AnimationEvents.html

avatar image Macro · Jan 30, 2014 at 08:37 AM 0
Share

Isnt that using the legacy animation system not mecanim?

avatar image demented_hedgehog · Aug 05, 2015 at 02:29 AM 0
Share

@aeroson $$anonymous$$aybe it's just me but the idea of having a system where changing an animation breaks the code seems horrifying. ($$anonymous$$aybe my understanding is broken). State $$anonymous$$achine Behaviours also seem broken because their link to the monobehaviours is similarly tenuous (again maybe just my broken understanding).

2 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by Macro · Sep 04, 2014 at 04:54 PM

If it helps anyone else I ended up re-visiting this problem and the solution I found was to use both the current animation state and the current clip state (or next) to get the details on if the current state was one we cared about, and if so get the normalized time from it, then get the clip state info and get the clip from it, then multiply the clip length by normalized time to give an indication as to when the clip will be over.

             var animationState = _animator.GetCurrentAnimatorStateInfo(0);
             if (animationState.nameHash != YourAnimationNameHash) { return; }
 
             var animationClips = _animator.GetCurrentAnimationClipState(0);
             if (animationClips.Length == 0)
             { throw new Exception("No clips associated with animation"); }
 
             var animationClip = animationClips[0].clip;
             var animationTime = animationClip.length*animationState.normalizedTime;
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image chilemanga · Nov 11, 2015 at 11:18 PM 0
Share

I had a similar issue and I needed to calculate animation time in a loop inside a Coroutine. So my code, using your example had to look something like this:

     // The code you posted here...
     var animationState = _animator.GetCurrentAnimatorStateInfo(0);
     if (animationState.nameHash != YourAnimationNameHash) { return; }
  
     var animationClips = _animator.GetCurrentAnimationClipState(0);
     if (animationClips.Length == 0)
     { throw new Exception("No clips associated with animation"); }
 
     // Wait for end of frame to get proper animation length
     yield return null;
     var animationClip = animationClips[0].clip;
     float clipLength = animationClip.length;
 
     for (int i = 0; i < itemsToAnimate.Count; i++) {
         // some code... blah blah
 
         // Wait for next frame again
         yield return null;
         // Normalize animation duration
         AnimatorStateInfo animStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
         float animDuration = animStateInfo.length - ( clipLength * (animStateInfo.normalizedTime % 1) );
         yield return new WaitForSeconds( animDuration );
 
         // Do whatever you want after this animation has looped
     }
 

Important: Note that normalizedTime could become a value that's not necessarily between 0~1, so that's why I use the module operator with (animStateInfo.normalizedTime % 1).

avatar image
3

Answer by aeroson · Jan 30, 2014 at 02:01 PM

Seems like AnimationEvents added thru animation viewer are not compatible with mecanim.

But you can add new curves and events in the model's Animations tab. Curves and events added thru here are usable in mecanim.

It's well explained here (especially the mecanim video tutorial): http://answers.unity3d.com/questions/378420/trigger-event-on-specific-frame-of-an-animation.html

So i have added new curve called used starting at 0 ending at 1. Added new float called used in my animator controller. In my code i then did animator.GetFloat("used ") and it works !

Quick image tutorial

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Macro · Jan 30, 2014 at 02:05 PM 0
Share

The link provided here is very useful, will look into it more and if it solves the problem will give you the answer although it is technically not addressing the animation length problem more giving an alternative way to solve the underlying problem.

avatar image aeroson · Jan 30, 2014 at 02:14 PM 0
Share

I dare to say this is much better solution than being bound to one specific animation. What if you want to change it ? You would have to change all your constants in code. This way your animation guy can easily adjust it to fit the needs.

avatar image Macro · Jan 30, 2014 at 03:18 PM 0
Share

It is not so much bound, basically in my scenario I have playmaker start an attack animation based upon the players current state, then once that begins the player can chain together combos based upon button presses. The problem I had was telling when an animation had ended so I could start the next one or revert back to idle, however its not quite as simple as that with mecanim as you are transitioning not stopping and starting. So it made more sense to get the animation length, wait for that period and see what buttons (if any) the user presses, then after that time has elapsed start the next animation, however I was not sure which was the best way to get the length. This way it is a generic action which can be applied to any animation and will wait for the elapsed time to expire before actioning anything, and does not need any variables in the animator, as from my point of view game state should be controlled by the game not the animator, so I prefer to not alter variables and things in animations however given the constraints maybe this is a more robust solution even if it mixes concerns and adds a slight level of complexity.

avatar image Macro · Feb 02, 2014 at 09:53 AM 0
Share

Upon further investigation this appears to be a pro feature, which is good, but I cannot find a way to achieve this without hard-coding in the free version of Unity.

Your answer

Hint: You can notify a user about this post by typing @username

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

Answers Answers and Comments

21 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Mecanim not playing animation correctly 1 Answer

How do I check, and change, the current frame/time of a sprite animation in Unity 4.3? 0 Answers

How to get length of animation in Mecanim? 1 Answer

Animation Impulse System? 1 Answer

Problem with Animator.Play() 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges