- Home /
Root motion in child not moving with parent
Hi!
So I have set a moving platform like so:
public class MovingPlatform : MonoBehaviour
{
public void AttachTransform(Transform transform)
{
transform.parent = this.transform;
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
other.transform.parent = transform;
}
}
private void OnTriggerExit(Collider other)
{
PlayerController player = other.GetComponent<PlayerController>();
if (other.CompareTag("Player") && !player.StateMachine.IsInState<Locomotion>())
{
other.transform.parent = null;
}
}
private void OnTriggerStay(Collider other)
{
if (other.CompareTag("Player"))
{
PlayerController player = other.GetComponent<PlayerController>();
if (player.StateMachine.IsInState<Jumping>())
OnTriggerExit(other);
}
}
}
The extra AttachTransform function is just for when the character is going to grab the ledge so it can be attached earlier and align properly (auto-grab system).
When the character is hanging from this ledge (with root motion enabled), they are a child for the object holding this script, and the character correctly moves up and down with the platform.
The problem comes whenever I press space to climb-up. The animation plays at the point where I pressed it and the character doesn't continue to move up with the ledge, so the character ends up standing up in thin air and falls. This issue also occurs when shimmying left or right. I have checked that the character is definitely a child of the platform when climbing up, so that is not the issue.
Climbing up itself is never an issue on stable non-moving platforms. The code looks like this:
private void ClimbUp(PlayerController player)
{
player.camController.State = CameraState.Grounded;
player.Anim.SetFloat("Speed", 0f);
player.Anim.SetFloat("TargetSpeed", 0f);
if (Input.GetButton("Sprint"))
player.Anim.SetTrigger("Handstand");
else
player.Anim.SetTrigger("ClimbUp");
isClimbingUp = true;
}
And in the state update method;
if (isClimbingUp)
{
if (animState.IsName("Idle") || transInfo.IsName("ClimbUp -> Idle"))
{
player.StateMachine.GoToState<Locomotion>();
}
return;
}
Does using a root motion animation stop the player moving with the ledge? Its very unusual because the player did successfully climb up on a small number of tries, but I didn't change anything in the code that would have fixed it. It was like by chance.
Answer by JonPQ · Dec 21, 2018 at 10:50 PM
at a guess.... you probably want to make sure that the animation on the character is not animation the root's world position... and only animating children of the root... say from a helper bone, or pelvis and onward from there.
You might also want to turn off all of your collision code once character is grabbing ledge and parented to the ledge.... no need for collisions, and they might just make some strange code execute. Turn the collisions back on after the climbing sequence has finished.
Thanks for the answer.
Collisions are disabled during climbing. So perhaps your suggestion about it animating the world position is correct. I think that it is the world position changing. How would I work around that if I cannot edit the animations?
EDIT: Added some code that literally adds the change of position of the platform to the player's position if root motion is being applied. Its something. $$anonymous$$akes it look worse when standing on the platform I think because no Y root motion is applied perhaps? I will try just applied the change in position of the platform without the object being a child.
EDIT 2: I tried what I said above and that seems to have solved my issue. The only issue I have is that sometimes it looks like player is trying to catch up with the platform. I can probably figure it out myself, but if you have any immediate idea that comes to $$anonymous$$e, feel free to tell. :)
workarounds ...hrmmm... yes, as you are doing... apply opposite position translate to what is going on in the root motion. maybe a better option would be to parent your character with another empty gameObject above it. maybe all the time, or maybe only when its grabbing the ledge. the parent object could maybe be at the grab point on the ledge, with an offset to your child's root... it "might" avoid the root motion affecting global position... but not sure
Answer by golaod · Jun 09, 2021 at 08:00 PM
It's an old topic, but I just had the same issue. I moved my old project to new unity and new render pipeline system and same script, same player and same platform stopped working.
After checking all the topics with rigidbody, OnTriggerStay, position correction and so on, I found out that there is 'auto sync transforms' option which was not enabled in my new project. When I reenabled it, things went back to normal. (Edit -> Project Settings -> Physics (or Physics 2d) -> Auto Sync Transforms