Maintaining upwards velocity with Rigidbody2D MovePosition while moving against a wall horizontally

Hey :)

I'm working on a Unity 2D project and using a Rigidbody2D for my character. I've set up a jump mechanic where I calculate the jump velocity and apply it to the Rigidbody using the MovePosition method. However, I've encountered an issue. When I jump and simultaneously move against a wall (which has another collider), the character loses its upwards velocity, causing the jump to not reach its intended height.

I'm looking for suggestions on how to prevent this loss of upwards velocity when the player jumps and moves against a wall simultaneously. My goal is to allow the player to continue moving in that direction without sacrificing the effectiveness of the jump height.

Any insights on how to address this issue would be greatly appreciated. Thanks! :)

MovePosition isn't a velocity-based movement, it's just movement to a position in a single simulation step. When you call this, prior to the next simulation step a velocity is calculated to move the Dynamic/Kinematic body to the specified position and the current velocity is stored, linear drag is stored/removed too. The simulation step happens and the old velocity/linear drag are restore.

You cannot use MovePosition in conjunction with velocity-based movement or at least in a single simulation step, only one thing can happen as they are conflicting movement objectives.

Maybe I was a little bit confusing. I store a velocity on my own which i use to change the position.

_Rgb.MovePosition(position + (_Velocity * deltaTime));

_Velocity is a Vector2.

With the Y value getting changed through two methods.


_Velocity.y = _Param.InitVelocity;

And Gravity:

_Velocity.y += (_Velocity.y > 0 ? _Param.GravityUp : _Param.GravityDown) * deltaTime;

Value X getting changed through a single method Move:

            _Velocity.x = _MovementValue * _Param.MovementSpeed * (isGrounded
                ? _Param.GroundModifier
                : (_Velocity.y > 0 ? _Param.AirModifierUp : _Param.AirModifierDown));

When I stand against a wall and want to jump on that said wall without moving left or right I will make the jump on top.
If I stand against the same wall and want to jump while moving against the wall. I will not make the jump anymore.

Thats basically my issue :)

Isn't the answer related to how you're detecting collisions on this Kinematic body? You certainly wouldn't be doing this with a Dynamic body as it has its own velocity, friction etc. For this kind of explicit positioning, you'd typically use a Kinematic body and physics queries to detect the environment around it.

If you are ignoring velocity on a Dynamic body then perhaps it's simply because of wall friction or it's hitting some corner of a collider. Multiple colliders next to each other are not a continuous surface to physics no matter how well you align them. This only continuous surface in physics is the edge shapes produced by the EdgeCollider2D and CompositeCollider2D (outline mode).

I previously used the dynamic Rigidbody with the velocity application instead of the MovePosition method. The issue was the same which is why I was trying the other method.

Both bodies have a physics material with 0 friction attached. I hoped that i could use the dynamic collision detection to prevent the player from moving through other colliders. But if thats not possible I guess I need to implement the physics query. :(

I think you're getting into a bit of a tangle here. You're saying you had the exact same problem when using velocity so you changed to using "MovePosition" in the hope it would somehow solve the issue without actually knowing the cause of issue? The problem with this approach is that you can end up exactly where you started and it seems that's where you are.

The main thing here is to find out why this was happening. In the end, it's as I said above. It's either friction OR it's a contact. There is nothing else. If you had a situation where you could consistently reproduce it then you should easily be able to figure it out.

if it's because of a contact then you could look at the contacts and their normals to see if you're getting a normal facing away from the direction you're trying to move. There's even a contact/normal gizmo display you can turn on the 2D physics settings to help with this. The contacts are also displayed in the inspector for each Rigidbody2D/Collider2D (see the "Info > Contacts" rollout) so a wealth of information available there.

I never said it's not possible; I qualified using MovePosition with a Dynamic Rigidbody2D only.

1 Like

It seemed like someone on my project had played with the friction values. So I am sorry to have wasted your time :(

But thanks for the information about the Gizmo Normal settings! Will be very helpful for me in the future :)

1 Like

Not a waste of time if it solved your problem and got you moving forward. :)

Good luck!

1 Like