- Home /
Mixing Unity Mecanim and Scripted Bones/States
The problem is that when the Animator
component is enabled, it stops any bone movement/rotation in script. Even if you mask out the area where the bone you want to modify is, the animator still impedes.
Version: Unity 4.3.1f1
I noticed that if I enable Animate Physics
on the Animator
component that I am able to edit the bone rotations but the pose seems to skew the movement on the ground but I think this is because it runs Mecanim in FixedUpdate()
.
Modifying the bone in the LateUpdate()
loop works but if down the line I need something to run after, then I would be almost out of luck. Is this still the only means of working around this issue?
Update 2014-1-20: I just stumbled upon the Optimize Game Objects
option under the rig section of your model. This is a great feature to save memory and probably CPU but there is NO way to mix script bones with Mecanim when you enable this feature. Even when you use the Expose Transform
option, modifying those transforms has absolutely no effect. I assume this is because it is mainly thought of as a read-only type of nodes to attach to or spawn things.
Previous Update: I just noticed the following quote from this article:
"Update 5 Dec 2013: Today I noticed that Unity 4.3 has added the Animator.Update() which could be used to implement the ragdoll to animation blend more elegantly without the LateUpdate() trickery. I'll have to update this example when I have time."
I do not see Animator.Update()
in the script reference and I am not sure how to hook/use this loop. Is this new function the way to go and how can it be used?
Edit: It seems that since Animator.Update()
is not a virtual
method that you can not override it and they made Animator
a sealed
type which prevents inheritance (so you can't hide and extend the method).
The main question of this section is: How do I mix Mecanim with scripts for some of the bones?
I know there is a `Animator.SetLookAtPosition` (and Animator.SetLookAtWeight
) methods but rather than an IK type look method, I have a head look script (which you can see in this question) that responds to the mouse.
I can think of a workaround where I make a blend tree with parameter for head rotation that blends left, right, up, down head animations and then adjust the parameter in the head look script. But this seems like a lot of work for simple stuff and might be a problem with the transition time (lagging behind mouse).
I really like the Mecanim system to use the IK system for holding a weapon and the blending of animations but if there are no proper setups then what kind of best alternatives are there?
Possible Alternatives (haven't used):
IK:
Inverse Kinematics by Dogzer - includes elbow targeting (Mecanim currently does not have this feature in Unity 4.3.1f1)
Animation Blending/Transitioning:
I can't find any
Here are some other links talking about this issue:
How to combine mecanim and script based bone movement/animations?
Mecanim: modifying animation in script when animate physics in on, impossible ?
Are bone transforms in LateUpdate the transforms for the next or previous frame?
Exact order of operations to render a frame (character animation problem)
If you need something later than LateUpdate, there is OnPreRender and then there is Script Execution Order for even more Control.
The way it's supposed to be is of course by using OnAnimatorI$$anonymous$$, but I$$anonymous$$ is pro only - have you tried if the method still gets called in Free? http://docs.unity3d.com/Documentation/$$anonymous$$anual/Inverse$$anonymous$$inematics.html
Upvote for Asking a question how you're supposed to ask questions here ins$$anonymous$$d of "write code for me"
@Happy$$anonymous$$oo Sorry, I have not tried OnAnimatorI$$anonymous$$()
in free as they make it hard to switch back and forth from pro to free. That function is called before I$$anonymous$$ is updated by $$anonymous$$ecanim so it doesn't help with modifying bones after everything is said and done.
Answer by duck · Jan 29, 2014 at 08:32 PM
Yes you are correct about "Animate Physics" checkbox - it simply makes Mecanim update in sync with the physics timestep instead of the game's framerate, so adjusting bones in LateUpdate when using "Animate Physics" will give weird unpredictable syncing problems depending on the framerate the project is running at.
As you've found, you can modify the bones successfully in LateUpdate() when Animate Physics is unchecked, and if you need further scripts to be executed after these particular LateUpdate scripts, you can use Unity's Script Execution Order controls to ensure other scripts with LateUpdate functions occur afterwards.
Animator.Update() allows you to manually update the animator according to whatever timestep you pass. This is useful when you want control over the 'deltaTime' that the animator is using rather than letting it play back according to the current timeScale.
You can use this for timescale-independent animation. Here's an example of an explosion and physics playing with the timescale set to 0.03, so it's super-slow motion, and I'm manually calling Animator.Update(t) on the controller for the landing gear of the aeroplane, where 't' is calculated using Time.realtimeSinceStartup so the wheels are extending and retracting at a normal speed, within the slow-motion scene.
Slightly weird demo, I know - but I happened to have this project open at the time a few days ago when someone else asked about Animator.Update() :)
@duck Thanks for the response! Do you know of any solution for the problem proposed in the "Update 2014-1-20" section of the main post about the Optimize Game Objects
setting?
I moved onto networking waiting for this issue so I am not as acquainted/"in the trenches" as I was days/weeks ago with this topic. Hopefully this will all come together when I get back to it.
The Animator.Update()
demo and explanation was awesome!