Greetings everyone!
I have created a hovercar following this tutorial video:
There’s a sample package of my scene attached for you to test this out.
I really like how the hovering feels, but there is a problem with the controller script. when turning and accelerating at the same time, it shakes the car quite much. Adding angular drag seems to be one option, but I’d like to be able to do different vehicle designs with more angular turn rate etc.
I feel the problem is related to how the engines are kind of off-sync because of the nature of the code (loop), each adding slightly different amount of force to the thrusters when they are in different heights to each other.
I’ve thought of a few solutions, but not been able to turn them into anything solid yet:
- Somehow limit or ignore the small x rotations - if you look at the x rotation in playmode, it goes nuts when it shakes. I tried experimenting with some x/ z limitations on an if statement, without much effect. it is commented out in the carcontroller script.
- Sync the engines in script somehow
Any ideas on this?
Car Controller script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CarController : MonoBehaviour {
public float acceleration;
public float rotationRate;
public float hoverHeight = 3f;
public float turnRotationAngle;
public float turnRotationSeekSpeed;
public float rotationVelocity;
public float groundAngleVelocity;
private Rigidbody carRigidbody;
// Use this for initialization
void Awake ()
{
carRigidbody = GetComponent <Rigidbody>();
}
// Update is called once per frame
void FixedUpdate () {
if (Physics.Raycast (transform.position, transform.up * -1, hoverHeight)) {
carRigidbody.drag = 1;
Vector3 forwardForce = transform.forward * acceleration * Input.GetAxis ("Vertical");
forwardForce = forwardForce * Time.deltaTime * carRigidbody.mass;
carRigidbody.AddForce (forwardForce);
} else {
carRigidbody.drag = 0;
}
Vector3 turnTorque = Vector3.up * rotationRate * Input.GetAxis ("Horizontal");
turnTorque = turnTorque * Time.deltaTime * carRigidbody.mass;
carRigidbody.AddTorque (turnTorque);
//if (carRigidbody.angularVelocity.z >= .1) {
Vector3 newRotation = transform.eulerAngles;
newRotation.z = Mathf.SmoothDampAngle (newRotation.z, Input.GetAxis ("Horizontal") * -turnRotationAngle, ref rotationVelocity, turnRotationSeekSpeed);
newRotation.x = newRotation.normalized.x;
transform.eulerAngles = newRotation;
// }
// "original" Vector3 newRotation = transform.eulerAngles; newRotation.z = Mathf.SmoothDampAngle (newRotation.z, Input.GetAxis ("Horizontal") * -turnRotationAngle, ref rotationVelocity, turnRotationSeekSpeed); transform.eulerAngles = newRotation;
}
}
Engine script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HoverMotor2 : MonoBehaviour {
public float thrusterStrength;
public float thrusterDistance;
public Transform[] thrusters;
private Rigidbody carRigidbody;
void Awake ()
{
carRigidbody = GetComponent <Rigidbody>();
}
void FixedUpdate () {
RaycastHit hit;
foreach (Transform thruster in thrusters) {
Vector3 downwardForce;
float distancePercentage;
if (Physics.Raycast (thruster.position, thruster.up *-1, out hit, thrusterDistance)) {
distancePercentage = 1-(hit.distance / thrusterDistance);
downwardForce = transform.up * thrusterStrength * distancePercentage;
downwardForce = downwardForce * Time.deltaTime * carRigidbody.mass;
carRigidbody.AddForceAtPosition(downwardForce, thruster.position);
}
}
}
}
}