在Unity中有更好的方法来编写这个转向角,使其感觉更自然吗?

huangapple go评论65阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年2月27日 01:14:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75573699.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定