I have a car controller I’ve been working on, still messing around with it but I have the basic setup for it. The only problem I’m having, ultimately, is turning the car. here’s the code that rotates it:
void TranslateWheels()
{
float ax = Input.GetAxis(ControlSettings.steerInput);
float c = (currentSpeed / 10);
bool handBrake = Input.GetButton(ControlSettings.brakeInput);
if (c > 0.6f) c = 0.6f;
if (handBrake) c *= 2;
lerpTurn = Mathf.Lerp(lerpTurn, c, 1 * Time.deltaTime);
// here's where the turning takes place
if (ax > 0.5f)
{
rg.transform.Rotate(rg.transform.right, lerpTurn);
}
else if (ax < -0.5f)
{
rg.transform.Rotate(-rg.transform.right, lerpTurn);
}
//
ax *= 45;
for (var i = 0; i < WC.Count; i ++)
{
WheelCollider w = WC[i];
Transform t = wheels[i];
if (w.name.ToCharArray()[0].ToString() == "F") w.steerAngle = ax;
float rot = rg.velocity.sqrMagnitude * 10;
Vector3 vec = new Vector3(-90 + rot, w.steerAngle, 90);
t.localEulerAngles = vec;
}
}
I’ve tried replacing rg.transform.right with rg.transform.TransformDirection(Vector3.right), but no change. The car does turn, depending on the angle. But once the rotation angle of x nears 90, or -90, it starts to turn less until it stops. So it turns the car, but not consistently all the way around.
My achilles heel has always been dealing with rotation, so I’m not sure what other code to implement, if I’m missing something. Any help would be much appreciated, thank you.
Rotate() rotates around an axis (the first argument).
Generally a car turning left or right will therefore rotate around the up axis, like a top.
I see you rotating around rg.transform.right.
Is that your issue?
Ah okay, I mistakenly changed that, haha, my bad, I was trying to rotate it by the up axis. I was messing around with it before, forgot to change it back, but I’m still having the same problem. At low speeds, the car turns all the way around, but at higher speeds, the car gradually starts to turn less in the intended direction, but if I turn the opposing direction, it turns hard, and I get my turning back. It’s a very confusing issue that I can’t put a finger on. I’ll provide a link to a video in a minute, hopefully it’ll showcase my issue better than I’m explaining it.
Oh actually if rg
is a Rigidbody
, don’t use Rotate()
on the transform.
Instead, get the rotation out (it’s a Quaternion) from the transform.rotation
, do a .Rotate() on that variable, then put it back using the rg.MoveRotation()
method.
Otherwise you are confusing the physics system because assigning to transform.rotate bypasses the physics.
Ah, thanks! I redid the rotating portion of the code, and it has a smoother turn, but I’m continuing to have the same problem I had before. If you want to take a look, this is a link to the video kind of showcasing the way the car handles:
https://www.dropbox.com/s/e7ds3b32via11sm/Unity 2018.2.18f1 Personal (64bit) - CustomCarController.unity - CustomCarController - PC, Mac & Linux Standalone DX11 2021-03-10 12-01-31.mp4?dl=0
And, to add, this is with the updated scripting, here is the new rotation code:
lerpTurn = Mathf.Lerp(lerpTurn, c, 1 * Time.deltaTime);
Vector3 rotate = new Vector3(0, lerpTurn, 0);
Quaternion q = Quaternion.Euler(rotate);
Quaternion l = Quaternion.Euler(-rotate);
if (ax > 0.5f)
{
rg.MoveRotation(rg.rotation * q);
}
else if (ax < -0.5f)
{
rg.MoveRotation(rg.rotation * l);
}
Btw, thanks for telling me about using proper rotations with rigidbody, I’ve been using Rotate functions for the most part.
EDIT: I did want to explain, in the video, the car handles pretty good at first, but after speeding up and trying to turn around the blocks, it barely turns at all.
1 Like
You’re welcome! It’s critical otherwise collisions go haywire because the physics system tries to resolve it.
I think if you’re still seeing some turning discrepancies you have to isolate if it is really the wrong rotation going in, or some other factor such as friction with ground, angular drag, just merely perception or something else entirely.
To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.
Doing this should help you answer these types of questions:
- is this code even running? which parts are running? how often does it run?
- what are the values of the variables involved? Are they initialized?
Knowing this information will help you reason about the behavior you are seeing.
Alright, I’ll kind of tamper with it and look at some values to see what’s going on. Thanks for the help
1 Like
Is this the root of your problems? It seems to connect your rotation to your speed in some mysterious magic number-y way.
alright so the c variable is supposed to control the low speed turning. Here’s a little snippet of what’s going on:
float c = (currentSpeed / 10);
if (c > 0.6f) c = 0.6f;
This will tie in the speed of the car. So if the car’s speed is 0, you won’t be able to turn the car. But once you start driving, you’ll be able to turn the car. This ultimately ties into the lerpTurn variable. So far, I’ve been watching the lerpTurn variable and it seems to be doing what I want it to, for now anyway.