'How to lock position of physic body in z axis in Unity 3D

I am developing a 2.5D game. In that game I want my character (which has Rigidbody component attached to) to just move on x and y axises. So I use this code snippet:

private void LockZAxis () {
    Vector3 currentPosition = _rigidbody.position;
    currentPosition.z = 0;
    _rigidbody.position = currentPosition;
}

I call this LockZAxis method in the end of both Update, FixedUpdate and LateUpdate. But it doesn't work. When my character run forward for a while, its z position is still changed.

For additional information, in my code, there are two times I manipulate the position of RegidBody. The first is when my character jump, that time I use this:

jumpVelocityVector = Vector3.up * jumpForceUp + transform.forward * jumpForceForward;
_rigidbody.velocity = jumpVelocityVector;

And each frame when I want my character to move a bit faster, so in the update method, I have this:

void Update () {
    Vector3 newPosition = transform.position + transform.forward * speed * Time.deltaTime;
    newPosition.z = 0;
    _rigidbody.MovePosition (newPosition);

    LockZAxis ();
}


Solution 1:[1]

A rigidbody is used to simulate physics, by setting the rigidbody's position every frame you're essentially teleporting the character every frame. You can restrict movement in z-axis, this will prevent it to move in z-axis when physics is applied, which is what a rigidbody typically is used for.

Here is how to restrict rigidbody positional change:

Here is how to restrict rigidbody positional change

If you run your LockZAxis() after you've changed the position it should teleport the object to the z-position of 0 every frame. Please make sure that the z-axis is the correct axis. You can debug this by pausing a running game and manipulating the Transform values to see how each axis moves your Object.

Solution 2:[2]

Is physics gravity set to only affect the Y position ? Physics.gravity = new Vector3(0, -1.0F, 0);

And set these also rigidbody.angularVelocity = Vector3.zero; rigidbody.velocity.z=0;

make sure your rigidbody is set to kinematic since you are using Rigidbody.moveposition() and using moveposition() will directly effect velocity internally on a kinematic rigidbody

Try using moveposition() for you jump instead of velocity

Solution 3:[3]

Here is how you can do it with C# Script:

Freeze All Positions

rigidbody.constraints = RigidbodyConstraints.FreezePosition;

Freeze Specific Positions:

rigidbody.constraints = RigidbodyConstraints.FreezePositionY | RigidbodyConstraints.FreezePositionZ;

Unity Documentation

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 glenneroo
Solution 2 Jasonbryant28
Solution 3 Single-byte