Somethin wrong with my script?
Hi! I've recently made a script for my car movement and discovered some issues with it. Maybe you have some solutions?
The car acceleration is very inconsistent ( accelerates slow and the top speed is way too high ) and also my brakes respond too late.
The rigidbody is making my car move weirdly( and if I increase the mass my car just goes straight through the ground )
Maybe I've done something wrong with my code or I didn't implement something into it? This is the code :
using UnityEngine; public class player : MonoBehaviour { [SerializeField] private Transform rsf; [SerializeField] private Transform rdf; [SerializeField] private Transform rsb; [SerializeField] private Transform rdb; [SerializeField] private WheelCollider crsf; [SerializeField] private WheelCollider crdf; [SerializeField] private WheelCollider crsb; [SerializeField] private WheelCollider crdb; [SerializeField] private float turnAngle = 5; [SerializeField] private float speed = 1; private float forwardValue; private float rightValue; private float currentSpeed; [SerializeField] private Rigidbody rigidbody; public float GetCurrentSpeed() { return currentSpeed; } public static player Player; void MovePlayer() { //transform.Translate(Vector3.forward * forwardValue * speed * Time.deltaTime); //transform.Translate(Vector3.right * rightValue * speed * Time.deltaTime); //transform.Rotate(Vector3.up * rightValue * rotationSpeed * Time.deltaTime); } void GetInput() { forwardValue = Input.GetAxis("Vertical"); rightValue = Input.GetAxis("Horizontal"); } // Update is called once per frame void Update() { GetInput(); Accelerate(); Steer(); WheelsUpdate(); } void Accelerate() { crsb.motorTorque = forwardValue * speed; crdb.motorTorque = forwardValue * speed; currentSpeed = rigidbody.velocity.magnitude; } void Steer() { crsf.steerAngle = rightValue * turnAngle; crdf.steerAngle = rightValue * turnAngle; } void WheelsUpdate() { GetSingleWheel(crsf, rsf); GetSingleWheel(crdf, rdf); GetSingleWheel(crsb, rsb); GetSingleWheel(crdb, rdb); } void GetSingleWheel(WheelCollider wheel, Transform wheelTransform) { Vector3 pos; Quaternion rot; wheel.GetWorldPose(out pos, out rot); wheelTransform.position = pos; wheelTransform.rotation = rot; } private void Start() { Player = this; if (rigidbody == null) { rigidbody = transform.GetComponent<Rigidbody>(); } } }
And this is a video with the car and its weird movement : https://imgur.com/a/smfwSfB
Answer by antonionae8 · May 24 at 06:35 PM
Here is the same code but shown better:
using UnityEngine;
public class player : MonoBehaviour {
[SerializeField] private Transform rsf;
[SerializeField] private Transform rdf;
[SerializeField] private Transform rsb;
[SerializeField] private Transform rdb;
[SerializeField] private WheelCollider crsf;
[SerializeField] private WheelCollider crdf;
[SerializeField] private WheelCollider crsb;
[SerializeField] private WheelCollider crdb;
[SerializeField] private float turnAngle = 5;
[SerializeField] private float speed = 1;
private float forwardValue;
private float rightValue;
private float currentSpeed;
[SerializeField] private Rigidbody rigidbody;
public float GetCurrentSpeed()
{
return currentSpeed;
}
public static player Player;
void MovePlayer()
{
//transform.Translate(Vector3.forward * forwardValue * speed * Time.deltaTime);
//transform.Translate(Vector3.right * rightValue * speed * Time.deltaTime);
//transform.Rotate(Vector3.up * rightValue * rotationSpeed * Time.deltaTime);
}
void GetInput()
{
forwardValue = Input.GetAxis("Vertical");
rightValue = Input.GetAxis("Horizontal");
}
// Update is called once per frame
void Update()
{
GetInput();
Accelerate();
Steer();
WheelsUpdate();
}
void Accelerate()
{
crsb.motorTorque = forwardValue * speed;
crdb.motorTorque = forwardValue * speed;
currentSpeed = rigidbody.velocity.magnitude;
}
void Steer()
{
crsf.steerAngle = rightValue * turnAngle;
crdf.steerAngle = rightValue * turnAngle;
}
void WheelsUpdate()
{
GetSingleWheel(crsf, rsf);
GetSingleWheel(crdf, rdf);
GetSingleWheel(crsb, rsb);
GetSingleWheel(crdb, rdb);
}
void GetSingleWheel(WheelCollider wheel, Transform wheelTransform)
{
Vector3 pos;
Quaternion rot;
wheel.GetWorldPose(out pos, out rot);
wheelTransform.position = pos;
wheelTransform.rotation = rot;
}
private void Start()
{
Player = this;
if (rigidbody == null)
{
rigidbody = transform.GetComponent<Rigidbody>();
}
}
}
Answer by rh_galaxy · May 24 at 11:25 AM
Your code is not readable (please select it and press the 101010 button), but if you say your car goes through ground if you increase mass seems like something is wrong with the colliders or collision detection. Rigidbody Collision Detection continuous and interpolate is probably what you want, now you have Discrete and No interpolation, be sure to change that, and also don't set the Project Settings->Physics->Default Contact Offset to low. The rest is a matter of adjusting Engine Power, Mass, Drag and Gravity to get the movement you want, and the wheel physics. Before you do that be sure to have the scale of your world and objects right, because if you change distances all of the above parameters need to be readjusted to make the car move the same, and it is not an easy task.