Reputation: 878
I have a coroutine that continuously moves platform using its Reigidbody, here's the code:
private IEnumerator MovePlatform(Vector3 startPosition, Vector3 endPosition)
{
float i = 0;
float rate = 1f / speed;
while (i < 1f)
{
i += Time.deltaTime * rate;
rigidbody.MovePosition(Vector3.Lerp(startPosition, endPosition, i));
yield return null;
}
StartCoroutine(MovePlatform(endPosition, startPosition));
}
rigidbody.MovePosition
is the correct way to move platform if I want my Rigidbodies to interact.
But here's the problem:
If platform moves vertically then object on top of platform continuously jumps while moving.
If platform moves horizontally then object on top of platform slides back and forth. Obviously that is not what I want them to do. I want object on platform stay still.
What I tried:
How can I achieve naturally good interaction between moving platform and object?
P.S. PLEASE👏NO👏PARENT👏METHOD👏THANKS👏
Upvotes: 2
Views: 774
Reputation: 1
I got behavior of a Rigidbody object staying still relative to a moving Rigidbody it is resting on. It does require setting the velocity manually to a certain extent, even though you said you don't want to do that.
For my case it is specifically applying to a character controller. Whenever the player OncollisionEnters() it checks if the colliding object has a platform tag, and if so grab the platform's rigidbody. At the end of character moving logic I then:
playerrigidbody.AddForce(currentPlatform.velocity).
The platforms I'm using are kinematic, animated using the animator set to animate physics, and have the same mass/drag as the player.
Again, probably not what you want, but if you are only concerned about one object getting glued, you can just Todd Howard as I did. Ignore all potential problems of the character hitting multiple moving things and getting confused, that is a fake problem.
Upvotes: 0
Reputation: 97
I have recently completed a project that accomplishes getting the rigidbody to stick to platforms that are changing both position and rotation. It takes lots of work, but I'm going to try to lay out a summary really quick.
The whole system relies on creating completely separate physics scenes (https://docs.unity3d.com/Manual/physics-multi-scene.html) for each moving platform, which is used to simulate the physical relationship between the moving platform and the rigidbody rider. The only difference between the simulation and the real scene is that in the simulation, the moving platform is not moving!
More detail:
At first, this simulation scene contains only a copy of the moving platform, except it does not move. When the rigidbody rider in our main scene collides with the moving platform, a copy of the rigidbody rider is added to the simulation at the same position/speed relative to the moving platform. Then, disable the controller on the main rigidbody rider so that it doesn't respond to player input. Do not disable the controller on the simulated rigidbody rider - it should continue to respond to the controller and freely move around on the simulated (non-moving) platform.
The simulated rigidbody rider is now walking around on a simulated non-moving platform. Now use MovePosition() and MoveRotation() to move/rotate the main rigidbody rider to match the simulated rigidbody character's position and rotation relative to the simulated platform. This way, when the simulated rigidbody character moves, the main rigidbody character will as well.
At this point, we have a functioning moving platform. As long as the rider to rider transformations are done with respect to the platform(s), it doesn't matter how the main platform is moving or rotating - the main rigidbody rider will stick to it perfectly. Though it will not be natural - for example, if the moving platform suddenly changes speed, the rider will change with it exactly.
When the main rigidbody rider is no longer colliding with the moving platform, we delete the simulated rigidbody rider from the simulation scene, and add full control back to the main rigidbody rider.
Upvotes: 0