Limit rotation on dynamic rigidbody
Hi! I have a player character which uses dynamic rigidbody. I want to use the built-in physics, but with a few exceptions. I want to constraint rotation and fall velocity, also speed and rotation itself.
I move and rotate my character using forces in FixedUpdate, and apply the constraints on LateUpdate.
void FixedUpdate()
{
if (!isLocalPlayer)
{
return;
}
Move();
Rotate();
}
private void LateUpdate()
{
if (!isLocalPlayer)
{
return;
}
ConstraintFallVelocity();
ConstraintRotation();
ConstraintRotationVelocity();
ConstraintSpeed();
}
void Move()
{
if ((Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0)) && !_spacePressed)
{
CmdShoot();
Vector2 velocityNorm = _rigidbody.velocity.normalized;
Vector2 velocityNormMirrored = new Vector2(velocityNorm.x, Mathf.Abs(velocityNorm.y));
if (velocityNormMirrored.y == 0f)
{
velocityNormMirrored.y = 1;
}
velocityNormMirrored.x = velocityNormMirrored.x * -1;
_rigidbody.AddForce(VectorHelpers.Rotate(VectorHelpers.DegreeToVector2(_rigidbody.rotation), 90).normalized * _force);
_spacePressed = true;
}
if ((!Input.GetKey(KeyCode.Space) && !Input.GetMouseButton(0)) && _spacePressed)
{
_spacePressed = false;
}
}
void Rotate()
{
float input;
if (Mathf.Abs(Input.acceleration.x) > Mathf.Abs(Input.GetAxis("Horizontal")))
{
input = Input.acceleration.x;
} else
{
input = Input.GetAxis("Horizontal");
}
_rigidbody.AddTorque(input * _rotationSpeed * -1);
}
void ConstraintFallVelocity()
{
if (_rigidbody.velocity.y < _maxFallVelocity * -1)
{
_rigidbody.velocity = _maxFallVelocity * _rigidbody.velocity.normalized;
}
}
void ConstraintRotation()
{
float rotationX = transform.eulerAngles.z;
Vector3 euler = transform.eulerAngles;
bool clamped = false;
// euler.z is between 0 and 360. For example, if it is rotated left it is 10, if rotated right, it is 350
if (euler.z > 180 && 360 - euler.z > _maxRotation)
{
clamped = true;
euler.z = 360 - _maxRotation;
} else if (euler.z < 180 && euler.z > _maxRotation)
{
clamped = true;
euler.z = _maxRotation;
}
if (clamped)
{
_rigidbody.angularVelocity = 0;
transform.eulerAngles = euler;
}
}
void ConstraintRotationVelocity()
{
_rigidbody.angularVelocity = Mathf.Clamp(_rigidbody.angularVelocity, -_maxAngularVelocity, _maxAngularVelocity);
}
void ConstraintSpeed()
{
if (Mathf.Abs(_rigidbody.velocity.x) > _maxSpeed || Mathf.Abs(_rigidbody.velocity.y) > _maxSpeed)
{
// clamp velocity:
Vector3 newVelocity = _rigidbody.velocity.normalized;
newVelocity *= _maxSpeed;
_rigidbody.velocity = newVelocity;
}
}
When I rotate, and the max rotation is reached, I experience a small jump in character movement. I think it is because though I took care of rotation limit, the new position has already been calculated.
Is there a right way to do this using dynamic rigidbody?
Your answer
Follow this Question
Related Questions
rigidbody.rotation locally; Help! 1 Answer
2d keep player upright 1 Answer
Rotating rigidbody problem 0 Answers
Question About NavMesh Agent and rotation 1 Answer
[VR] Rigidbody.AddForce() following controllers rotation 0 Answers