- Home /
Object pulling to a perpendicular angle when on a slope
I'm trying to implement a kart racer in Unity and I've put down the steering and acceleration. I'm using a sphere as the kart for easier movement so I needed to code in a program snippet to align the kart model with the normal of the surface it is currently on. However, whenever my kart drives onto a slope, it starts pulling to either the left or right and stops at a right angle. The steeper the slope is, the harder the pulling force. I have no clue what is causing this. Here's my code for reference.
public class KartController : MonoBehaviour
{
public float acceleration = 3f;
public float brakeSpeed = 2f;
public float steeringSpeed = 2f;
public float KartAlignmentSpeed = 1f;
public float gravity = 9.8f;
public Transform KartModel;
public Transform[] FrontWheels;
public Transform[] BackWheels;
public Transform SteeringWheel;
public GameObject chassis;
private GameObject sphere;
private float speed;
private float rotate;
private float currentSpeed;
private float currentRotate;
void Start()
{
sphere = transform.Find("Collider").gameObject;
speed = 0f;
}
void Update()
{
//Keep chassis at where the sphere collider is without rotating it
chassis.transform.position = sphere.transform.position;
//Inputs
if(Input.GetKey(KeyCode.X))
speed += acceleration;
if(Input.GetAxis("Horizontal") != 0)
{
int dir = Input.GetAxis("Horizontal")>0?1:-1;
float amount = Mathf.Abs(Input.GetAxis("Horizontal"));
rotate = (steeringSpeed*dir)*amount;
}
currentSpeed = Mathf.SmoothStep(currentSpeed,speed,Time.deltaTime*12f);
currentRotate = Mathf.Lerp(currentRotate,rotate,Time.deltaTime*4f);
//Model
KartModel.localEulerAngles = Vector3.Lerp(KartModel.localEulerAngles, new Vector3(0, 90 + (Input.GetAxis("Horizontal") * 15), KartModel.localEulerAngles.z), .2f);
//Wheels
foreach(Transform f in FrontWheels){
f.localEulerAngles = new Vector3(0, (Input.GetAxis("Horizontal") * 15), f.localEulerAngles.z);
f.localEulerAngles += new Vector3(0, 0, sphere.GetComponent<Rigidbody>().velocity.magnitude/2);
}
foreach(Transform b in BackWheels)
b.localEulerAngles += new Vector3(0, 0, sphere.GetComponent<Rigidbody>().velocity.magnitude/2);
//Steering wheel
SteeringWheel.localEulerAngles = new Vector3(-25, 90, ((Input.GetAxis("Horizontal") * 45)));
speed = 0f;
rotate = 0f;
}
void FixedUpdate()
{
sphere.GetComponent<Rigidbody>().AddForce(chassis.transform.forward*currentSpeed,ForceMode.Acceleration);
sphere.GetComponent<Rigidbody>().AddForce(Vector3.down*gravity,ForceMode.Acceleration);
sphere.transform.eulerAngles = Vector3.Lerp(chassis.transform.eulerAngles, new Vector3(0,chassis.transform.eulerAngles.y+currentRotate,0),Time.deltaTime*5f);
//This piece of code aligns the chassis to the ground below it
RaycastHit hit;
Transform cT = chassis.transform;
if(Physics.Raycast(cT.position,Vector3.down,out hit)){
cT.up = Vector3.Lerp(cT.up,hit.normal,Time.deltaTime * KartAlignmentSpeed);
}
else{
cT.up = Vector3.up;
}
cT.Rotate(0,sphere.transform.eulerAngles.y,0);
}
}
Edit:
I managed to find the issue that causes the kart to autopull to a hard 180 degree angle on slopes by changing line 50 of my code to
sphere.transform.eulerAngles = Vector3.Lerp(sphere.transform.eulerAngles, new Vector3(0,sphere.transform.eulerAngles.y+currentRotate,0),Time.deltaTime*5f);
However a residual problem still remains and that is, when I turn the kart sharply enough, it's Y rotation starts 'flipping' between x and x+-180 every frame for some reason. I narrowed the bug down to the above line as well. Something seems to change in the Lerp function. How would I fix this without bringing back the original issue?
Your answer
Follow this Question
Related Questions
Rotate around sphere using Quaternions with full radius 1 Answer
Weird issue with fire angle of projectiles changing 1 Answer
Rotate a sphere by its vertices... 1 Answer
"Free" rotation about a sphere 0 Answers
Lerp rotation relative to sphere 0 Answers