Hi,
Me and 2 classmates are creating a small racing game in the style of FZero. Now we have a basic movement script for driving the vehicle, but we are having one tricky problem.
While the acceleration and deceleration are going fine, implemented with rigidbody.addForce, the rotations are giving us more trouble. After we apply a rotation to the vehicle, it seems that Vector3.forward is not always pointing forward anymore. The consequence is that our vehicle does not move straight forward anymore.
We use a rigidbody and a spherecollider in Unity with gravity on. I’m not sure if this is the cause. Can it be that because of the friction with the floor plane, the rotation is not fully executed or something?
Here is the code in c# of our drive script:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
public class Drive : MonoBehaviour {
public float m_acceleration = 0.0f;
public float m_top_speed = 0.0f;
public float m_brake_decel = 0.0f;
public float m_steering_speed = 0.0f;
private float m_steering_treshold;
// Use this for initialization
void Start () {
}
void Awake()
{
m_steering_treshold = 0.1f;
}
// Update is called once per frame
void FixedUpdate () {
if (Input.GetKey(KeyCode.UpArrow))
{
Accelerate();
}
if (Input.GetKey(KeyCode.DownArrow))
{
Decelerate();
}
if (Input.GetKey(KeyCode.LeftArrow))
{
TurnLeft();
}
if (Input.GetKey(KeyCode.RightArrow))
{
TurnRight();
}
}
float kphTomps(float kph)
{
return kph * 3.6f;
}
void Accelerate()
{
if (rigidbody.velocity.magnitude < m_top_speed)
{
rigidbody.AddRelativeForce(Vector3.forward * rigidbody.mass * m_acceleration);
}
}
void Decelerate()
{
if (rigidbody.velocity.magnitude > (-m_top_speed / 10.0f))
{
rigidbody.AddRelativeForce(Vector3.back * rigidbody.mass * m_brake_decel);
}
}
void TurnLeft()
{
if (rigidbody.velocity.magnitude > m_steering_treshold)
{ transform.Rotate(Vector3.Normalize(Vector3.down * m_steering_speed * Time.deltaTime), Space.Self);
// Centripetal force = (m * v^2) / r
rigidbody.AddRelativeForce(Vector3.left *
(rigidbody.mass * (rigidbody.velocity.magnitude * rigidbody.velocity.magnitude) / m_steering_speed));
}
}
void TurnRight()
{
if (rigidbody.velocity.magnitude > m_steering_treshold)
{
transform.Rotate(Vector3.Normalize(Vector3.up * m_steering_speed * Time.deltaTime), Space.Self);
// Centripetal force = (m * v^2) / r
rigidbody.AddRelativeForce(Vector3.right *
(rigidbody.mass * (rigidbody.velocity.magnitude * rigidbody.velocity.magnitude) / m_steering_speed));
}
}
}
If someone has experienced the same problem, how did you solve it? Do we need to disable the gravity and use our own code for this or are there solutions out there that I missed?
Thanks in Advance,
Squibel
Edit: (PS) The values we are using currently for the public members are:
Acceleration = 10
Top_speed = 120
Brake_decel = 15
Steering_speed = 80