- Home /
Velocity from external objects
I'm making a platformer and I'm moving the player at constant speed while running. This is the initial code that was used for movement:
myRigidbody.velocity = new Vector2 (Input.GetAxis("Horizontal") * movementSpeed, myRigidbody.velocity.y);
The problem is that the player won't receive additional velocity from external objects. A couple examples:
Standing on a moving platform. The player won't move along with it.
Standing on a conveyor (Surface Effector 2D). The player won't move along with it.
I've figured out that the player wasn't moving along with those objects because it's X velocity was ALWAYS being set to 0 while not pressing the movement key so I fixed this by only setting the X velocity to 0 ONCE at the moment when the player stops running. The remaining problem:
While running on a moving platform or a conveyor (Surface Effector 2D) the additional velocity from these objects are not taken into account. For example - if the player has a movement speed of 10 and the conveyor is moving at a movement speed of 2 then when the player is running on the conveyor his total speed should be 10+2, but instead it's just 10.
I've had to find a way so that the player would run at a constant speed, while still being affected by external velocities. So this was my try at that:
// "currentWalkSpeed" keeps track of what speed the player is running at currently
// True only ONCE, when the player stops moving or changes running direction
if (prevHorizontal != horizontal && prevHorizontal != 0) {
// Stop the player
myRigidbody.velocity = new Vector2 (0, myRigidbody.velocity.y);
// Reset the walking/running speed buffer
currentWalkSpeed = 0;
}
// Calculate how much velocity we lost due to friction so we know how much to add to keep running speed constant
if (horizontal * prevVelocity > horizontal * myRigidbody.velocity.x) {
// Calculate how much velocity we lost due to friction
float velocityDiff = prevVelocity - myRigidbody.velocity.x;
// Current walking/running speed goes down due to friction
currentWalkSpeed -= velocityDiff;
}
prevHorizontal = horizontal;
// True if the player is not yet running at the constant speed. For example if it lost some speed due to friction
if (Mathf.Abs(currentWalkSpeed) < movementSpeed) {
// Calculate how much force we have to add to keep the player moving at constant speed
float diff = movementSpeed - Mathf.Abs (currentWalkSpeed);
// Add the force
myRigidbody.AddForce (Vector2.right * horizontal * diff, ForceMode2D.Impulse);
// Update the current walking/running speed
currentWalkSpeed += (horizontal * diff);
}
prevVelocity = myRigidbody.velocity.x;
This solution worked well, but there's a bug I can't solve:
If the player is running at a movement speed of 10 and while still running he lands on a conveyor that is moving of movement speed of 2, the player is still moving of a movement speed of 10 instead of 10+12. Only when I release the movement key and stop the player on a conveyor and press the movement key again, only then the player is running at a speed of 10+2 how he should.
Thank you very much for reading if you've got this far. I've been stuck on this problem for a week now and I'm contemplating whether I should drop the physics and just write up an additional script to objects with velocity which would transfer their velocity on collision with other objects where I could simply add that additional velocity to the current velocity of the object if needed. Any pros and cons to these two solutions?
Your answer
![](https://koobas.hobune.stream/wayback/20220612085117im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
how to jump at fixed height but faster 0 Answers
2D Physics Broke 1 Answer
How to move a rigidbody2D at a constant speed without AddForce? 1 Answer
Is there a way to lock velocity? 3 Answers
Running and Jumping problems of a 2D Endless Runner 2 Answers