Parenting to platforms is dumb. Getting the platform’s velocity is dumb. I’m kicking myself after stumbling on this cause it’s literally one function and it’s flawless.
Tl:dr is this: Rigidbody.GetPointVelocity.
Wherever you’re calculating the player’s target velocity on the ground (So like, input direction * target move speed), perform a raycast downwards. If the ground object you hit contains a rigidbody, do the following:
Get the rigidbody and point of the raycast hit.
pass that into Rigidbody.GetPointVelocity, store the output as a vector like ‘StoredPointVelocity’
Add the result to your target velocity (the variable you use to calculate acceleration).
if no rigidbody, set StoredPointVelocity to 0, 0, 0.
This will make it so the player quickly (but not instantly) catches up to the correct velocity (player velocity + platform velocity at the point the player is touching it), using whatever rigidbody physics you’ve already written. Since you’re changing the target speed in your own move function rather than directly applying forces, it works with any arbitrary velocity, including angular. You also don’t need to run any checks or distinguish between moving and non-moving, because if the platform’s velocity at the point of contact is 0, then nothing changes.
Importantly, unlike the parenting method, the player actually physically gains the velocity of the platform, so when you leave the platform you keep the momentum with zero jank.