I'm reading Unity Animation cookbook book. And I'm stuck at "Root Motion" topic. All I can understand now is Root motion allows the GameObject to move with the motion clip without coding. and it depends on the root node. But I can't imagine/understand how ? or what're that related properties like "Bake to pose" .. what's the pose..? I searched the web to find anyone talking about it.. but no helpful tutorials there! I tried to read from unity docs about the topic but it made it worse..
https://docs.unity3d.com/Manual/RootMotion.html
Please help me with example/link/replay
After spending more time searching/watching videos/ reading from other books to understand everything. I'll put my answer here for anyone face same difficulties understanding this topic
Treadmill vs root motion: There are two types of animation, treadmill and root motion. Treadmill means that the animation stays at the origin and we use code to move that asset around. Root motion means the motion is built right into the animation and it's the animation that determines how far something moves rather than code.
Then you have to watch this video to get an idea about how it looks in Blender and later in Unity when you import the character & animation
https://www.youtube.com/watch?v=d5z9dEnE4DE
Root Transform Rotation: This option captures the rotation of the root node and
applies it to the whole game object. You can set it to Bake Into Pose to disable the
root motion rotation. With this option selected, the rotation will be treated as a
visual effect of the animation and will not be applied to the game object. You
should set it to true for every animation that shouldn't rotate the character. You
can set the Based Upon option to one of the following options:
Root Transform Position Y: This option captures the vertical movement of the
root node and applies it to the whole game object. You can set it to Bake Into
Pose to disable the root motion in the Y axis. With this option selected, the Y axis
motion will be treated as a visual effect of the animation and will not be applied
to the game object. You should set it to true for every “on ground” animation
(unless it's a jump).
Root Transform Position XZ : This option captures the horizontal (XZ)
movement of the root node and applies it to the whole game object. You can set it
to Bake Into Pose to disable the root motion in the X and Z axis. With this option
selected, horizontal motion will be treated as a visual effect of the animation and
will not be applied to the game object. You should set it to true for all stationary
animations (such as Idle).
Good animations may combine both traditional(treadmill) and root motion ways.
The Body Transform (Pose) is the mass center of the character.
The Root Transform is a projection on the Y plane of the Body Transform (Pose) and is computed at runtime.
If you want to transfer the body transform to the gameobject first you have to transfer it to the root transform because that is the one that is applied to the gameobject transform. to transfer, for example, the XZ motion of the body transform to the root transform, you need to uncheck bake into pose option.
All right except "You should set it to true for every “on ground” animation (unless it's a jump)."
More correctly will be: "You should set it to True for every animation, where you will move Character GameObject by Axis Y by code (Unity Script), also are including the Jumping animation. If you will not move the GameObject of the Character along the Y-axis (by code), but want to implement "Jump" as the movement of bones (parts of the character's skeleton) from the jump animation, if it is present in the animation that was imported, you must set it to False. Many popular the Jumping "In-place" animations doesn't include the movement of bones, which will track the full bones movement at real Character Jump (say simple - in these animations the Root Node not up on demanding height)."
Related
Is it possible to apply root motion to non humanoid objects?
I need the object position to be incremental after every animation in animation controller. Position in default is reset to starting point of current clip. How do i prevent this? I need to make animation state machine with part of clips to make incremental changes in objects properties.
From Unity Documentation :
Generic Root Motion and Loop Pose
This works in essentially the same
as Humanoid Root Motion, but instead of using the Body Transform to
compute/project a Root Transform, the transform set in Root Node is
used. The Pose (all the bones which transform below the Root Motion
bone) is made relative to the Root Transform.
Apparently yes you can use the RootMotion on non-humanoid objects. You need to set the correct Root node in the Rig section for models and animations, this should be the node that actually contains the root motion that you want applied to your generic model.
Here's a thread about it on Unity Forums.
My player character moves around the world using the Animator with root motion activated. Basically, the AI system sets the velocities on Animator, which in turn controls the Animation clips that control character motion. As this is a standard feature that ensures very realistic animation without noticable sliding, I thought this was a good idea ...until I added Network synchronization.
Synching the characters over the Network using NetworkTransform and NetworkAnimation causes those two components to conflict:
NetworkTransform moves the character to whichever position the host commands.
NetworkAnimator syncs the animation vars and plays the Animation clips as host instructs it to, while those Animation clips also apply root motion.
The result is precise (meaning the character reaches the exact target destination), but very stuttering movement (noticable jumps).
Removing NetworkTransform, the host and client instances of the characters desynchronize very quickly, meaning they will end up at different positions in the world when solely controlled by the timing-dependant Animator.
Removing NetworkAnimator, client instances won't play the same animations as the host, if any animations at all.
I tried keeping both Components while disabling root motion for the Animator (on client only). In that case however, NetworkTransform does not seem to interpolate at all. The character just jumps from synched position to synched position in steps of about 0.02 units. Same with rotation.
NetworkTransform is configured to "Sync Transform", as the character neither has a RigidBody nor a CharacterController. All other values are the defaults: sync rate of 9 (also tried higher values there), movement threshold of 0.001, snap threshold of 5, interpolate movement = 1.
How do I get fluent root motion based movement on the Network? I expected that to be a standard scenario...
What you need is to disasble the Root Motion flag on non local instances but also to interpolate the rotation, not just the movement.
Moreover, an interpolation of 1 seems high, same as the thereshold of 5: those seem not realistic unless you are not using Unity standard where 1 unit = 1 meter. I would have a 25cm (0.25) interpolation for the movementand a 3 degrees for the rotation. The sync rate of 9 could be enough but in my experience it has to be recomputed based on the packet loss.
My main character moves by touching and holding him and then moving your finger left or right to move the character. To do this I just simply update the node's x position (walks left and right on a flat surface) in touchesMoved() with the x position of the touch location, and apply an animation depending on the direction he's moving.
I want to kind of take this to the next level and accomplish the same effect, but using physics, so that when I'm done moving him and release my finger, he may slide a little bit in the direction he was moving given the speed I was moving him at, if that makes sense. Does anyone know how I can accomplish this effect?
Would I have to do as I'm currently doing and update the position as it moves, but also apply a force/impulse at the same time? Kind of confused on how to approach this
Moving the physics body via force, impulse, or velocity will automatically update the player position.
So you will have to play around with the correct way to accomplish your goal. But based on this, what I would suggest is replace your .position code with .physicsBody!.velocity code in your touchesMoved. Then, on your touchesEnded, you can apply a bit of an impulse to give the player that little bit of an "on ice" effect to keep them going a tad.
You will need to experiment with how much velocity you want to get the character to move at the correct speed, and then you will need to play with the impulse figures as well to get it just right.
This could get a bit tricky though, in touchesMoved... because at some point you will want to reset the velocity to 0 (so they stop moving when your finger stops).
To do that, you will need to to use the .previousLocation from your touch object, and compare the distance of X moved. if the distance X moved is >0 (or some deadzone threshold) then apply the velocity; if the deltaX is 0, then set the velocity to 0.
This may actually be more complicated than just using .position to move the character, then having the character slide a bit with physics on touchesEnded.
You will have to play with it to get it right.
I have "GameObject 0" (GO0) with an animation controller that used parameters to transform states and is used as a wrapper for "GameObject 1"(GO1). "GameObject 1" has an animation controller that has Root Motion applied. Within GO1 there are 3 game objects whos animation is in the same animation clip as GO1.
This allows me to place GO1 in world coordinates and animate GO1's children in local coordinates to maintain relative positioning.
However, I am wish to move one of the children of GO1 to a world coordinate that is not relative to GO1. I have used script and Vector3.Lerp / Vector3.MoveTowards functions, but they are not working as expected. Is the Root Motion interfering with the Lerps?
I have change the script to add a new parent to the child object and animating the new parent. This seems to work but the rotation of the new parent is causing a new issue.
I do not understand, why jointed object can't look at target.
Example: 2 boxes with hinge joint (anchor is at the touching place) and a target object. When I say A-box to lookAt target, I think it will just turn on X-axis. But both of the boxes start to shake. Why?
Take a moment to reflect on what a call to LookAt is trying to do.
It's rotating the transform while ignoring physics.
That's bound to create problems, since you're not rotating the whole system, you're moving one part of it. Your rotation with LookAt is "fighting" with the adjustments the physics system is trying to make.
To solve that conflict you can do one of the following:
Rotate the entire system (both cubes). This will involve putting them all under one transform, and having that transform rotate.
Use a physics-based approach. It won't be too hard, but won't be as simple as a function call. You'll probably need a simple PID controller such as the one outlined in this thread.