TL;DR Here’s a video of the issue around the 0:05 mark : https://www.youtube.com/watch?v=YtqWx68WJpQ
I’m just trying to iron out some of the issues I’ve been running into lately. Not quite sure why the object does a rotation at specific angles, as if it’s avoiding crossing certain values or something.
The way I have it set up is that there’s a parent which controls the magnetic forces, normal rotation, and other rigidbody forces. On Awake(), a prefab containing the car model and collider is instanced at the origin of the parent.
I’m also running a Cinemachine camera…not sure if that would have any effect on things.
If you have any thoughts about this, I’d be happy to hear it!
EDIT:
Okay, so I have a few functions that handle rotations:
void Update()
{
//Turning Input
if (Input.GetAxis("Horizontal") != 0)
{
int dir = Input.GetAxis("Horizontal") > 0 ? 1 : -1;
float amount = Mathf.Abs((Input.GetAxis("Horizontal")));
Steer(dir, amount);
}
currentRotate = Mathf.Lerp(currentRotate, rotate, Time.deltaTime * rotSpeed); rotate = 0f;
}
void FixedUpdate()
{
CheckMagnet();
AlignToGround();
Turning();
}
void Turning()
{
//add torque relative to the currentRotate value
rb.AddTorque(transform.up * currentRotate * Time.deltaTime * rotSpeed);
}
public void Steer(int direction, float amount)
{
//calculate angle from current angle in the left or right direction
rotate = (steer * direction) * amount;
}
void CheckMagnet()
{
//Set the mask layer
mask = 1 << LayerMask.NameToLayer("TrackMask");
//Check if there is a track beneath the player
magnetized = Physics.Raycast(transform.position, -transform.up, out magHit, magnetRange, mask);
//Shoot four rays downwards in four directions
Physics.Raycast(transform.position + (transform.up * .1f) + (transform.forward * groundCheckDistance), -transform.up, out hitF, magnetRange, mask);
Physics.Raycast(transform.position + (transform.up * .1f) + (transform.forward * -groundCheckDistance), -transform.up, out hitB, magnetRange, mask);
Physics.Raycast(transform.position + (transform.up * .1f) + (transform.right * -groundCheckDistance), -transform.up, out hitL, magnetRange, mask);
Physics.Raycast(transform.position + (transform.up * .1f) + (transform.right * groundCheckDistance), -transform.up, out hitR, magnetRange, mask);
//Calculate the average of the raycast hit normals
Vector3 avNorm = (hitF.normal + hitB.normal + hitL.normal + hitR.normal) / 4f;
//Store the rotation
rotateToRoad = Quaternion.FromToRotation(transform.up, avNorm) * transform.rotation;
}
void AlignToGround()
{
//If there is track beneath the player
if (magnetized)
{
//move rigidbody to the hover height
rb.MovePosition(Vector3.Lerp(rb.position, transform.up * hoverHeight + magHit.point, hoverSpeed));
//rotate to the surface normal
rb.MoveRotation(Quaternion.Lerp(rb.rotation, rotateToRoad, alignSpeed));
}
else
{
//Fall with normal gravity and orient self
rb.MoveRotation(Quaternion.Slerp(rb.rotation, Quaternion.LookRotation(rb.velocity.normalized, Vector3.up), 0.025f));
rb.AddForce(Vector3.down * fakeGravity, ForceMode.Acceleration);
}
}