英文:
Is there a better way to write this steering angle in Unity to make it feel more natural?
问题
目前我在游戏中使用Unity的轮胎碰撞器(wheel colliders)来创建一辆车,希望使其更加真实,类似于Forza的感觉。
目前我的代码如下:
horizontal = horizontalInput * 40;
wheelColliders[0].steerAngle = horizontal;
wheelColliders[1].steerAngle = horizontal;
使用这种方法,驾驶时感觉不自然且转向角度不够灵活。
希望能得到改进的帮助,不胜感激,谢谢。
英文:
Currently I'm using unity's wheel colliders to create a car in a game that's meant to feel more realistic or Forza esc.
Currently I'm simply coding it like this:
horizontal = horizontalInput * 40;
wheelColliders[0].steerAngle = horizontal;
wheelColliders[1].steerAngle = horizontal;
using this it feels unnatural and sharp while driving, also the turning angle feels lackluster.
Any help on how I could improve would be greatly appreciated, thank you.
答案1
得分: 0
你可以添加一个PID控制器。它们在实际汽车中用于转向和制动辅助。
[Serializable]
public class PIDController{
[SerializeField] public float p;
[SerializeField] public float i;
[SerializeField] public float d;
private float oldError;
private float integralSum;
public float Update(float dt, float current, float target) {
float error = target - current;
float P = p * error;
float errorChange = (error - oldError) / dt;
oldError = error;
float D = d * errorChange;
integralSum = integralSum + (error * dt);
float I = i * integralSum;
return P + I + D;
}
}
public PIDController pid;
public float steerAngle, acceleration, velocity;
/////////////////////////
horizontal = horizontalInput * 40;
acceleration = pid.Update(Time.deltaTime, steerAngle, horizontal);
velocity += acceleration * Time.deltaTime;
steerAngle += (acceleration / 2 * Time.deltaTime + velocity) * Time.deltaTime;
wheelColliders[0].steerAngle = steerAngle;
wheelColliders[1].steerAngle = steerAngle;
我建议阅读关于PID控制器的文章,但这里是一个快速指南:
- p决定系统反应的强度
- d决定系统平稳的速度
- i决定系统迅速达到目标的速度
英文:
You could add a PID controller. They are used in real cars for steering and breaking assists.
[Serializable]
public class PIDController{
[SerializeField] public float p;
[SerializeField] public float i;
[SerializeField] public float d;
private float oldError;
private float integralSum;
public float Update(float dt, float current, float target) {
float error = target - current;
float P = p * error;
float errorChange = (error - oldError) / dt;
oldError = error;
float D = d * errorChange;
integralSum = integralSum + (error * dt);
float I = i * integralSum;
return P + I + D;
}
}
public PIDController pid;
public float steerAngle, acceleration, velocity;
/////////////////////////
horizontal = horizontalInput * 40;
acceleration = pid.Update(Time.deltaTime, steerAngle, horizontal);
velocity += acceleration * Time.delaTime;
steerAngle += (acceleration / 2 * Time.deltaTime + velocity) * Time.deltaTime;
wheelColliders[0].steerAngle = steerAngle;
wheelColliders[1].steerAngle = steerAngle;
I would recomend reading about PID controllers, but here is a quick guide:
- p is how strong you want your system to react
- d is how quickly you want your system to calm down
- i is how quick you want to force the system to reach the target
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论