'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:
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;
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 |