- 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
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