Unity - 为摩托车使用刚体 - 我该如何转弯?
Unity - Using a rigidbody for motorcycle - how do I turn?
我是 Unity 和刚体的新手,我想我可以通过尝试制作 3D Tron Light-cycle 游戏来学习。我使用圆柱体、球体和矩形的组合制作了我的玩家载具,如下所示:
我在拉长的球体上使用了刚体,并使用了以下代码:
public float accel = 1.0f;
// Use this for initialization
void Start () {
cycleSphere = GetComponent<Rigidbody>();
}
void FixedUpdate () {
cycleSphere.velocity = Vector3.forward * accel;
}
使车辆向前移动。我不确定是否有更好的方法来做到这一点,但如果有,请告诉我。
我已将主摄像头安装到车辆上,并禁用 X 旋转以防止它和摄像头滚动。
现在我想通过按 A 和 D 按钮让它转动。与原始 Tron 轻型自行车的 90 度转向不同,我希望它像普通车辆一样转向。
所以我尝试了这个:
void Update () {
if (Input.GetKey (KeyCode.A)) {
turning = true;
turnAnglePerFixedUpdate -= turnRateAngle;
} else if (Input.GetKey (KeyCode.D)) {
turning = true;
turnAnglePerFixedUpdate += turnRateAngle;
} else {
turning = false;
}
}
void FixedUpdate () {
float mag = cycleSphere.velocity.magnitude;
if (!turning) {
Quaternion quat = Quaternion.AngleAxis (turnAnglePerFixedUpdate, transform.up);// * transform.rotation;
cycleSphere.MoveRotation (quat);
}
cycleSphere.velocity = Vector3.forward * accel;
}
虽然上面的代码确实旋转了载具,但它仍然沿最后一个方向移动 - 它的行为更像是一个坦克炮塔。更糟糕的是,过多地按下 A 或 D 会导致它朝所需的方向旋转,过一会儿就会发疯,左右旋转,并带走相机。
我做错了什么,我该如何解决?
首先,我建议您将 Input.GetKey
更改为 Input.GetAxis
,这将在按下该键时优雅地增加或减少它的值。这将为您提供将作为速度应用的力矢量归一化的选项。然后基于该矢量,您必须调整力输入,以便 "front wheel" 将 "drag" 其余的 body 转向其他方向(左或右)。这不是理想的 "real world physics behavior" 因为前向力略大于侧向(左侧或右侧)力。
代码示例:
// member fields
float sideForceMultiplier = 1.0f;
float frontForceMultiplier = 2.0f;
Vector3 currentVeloticy = Vector3.zero;
void Update()
{
Vector3 sideForce = (sideForceMultiplier * Input.GetAxis("horizontal")) * Vector3.right;
Vector3 frontForce = frontForceMultiplier * Vector3.forward;
currentVelocity = (sideForce + fronForce).Normalize;
}
void FxedUpdate()
{
cycleSphere.velocity = currentVelocity * accel;
}
我是 Unity 和刚体的新手,我想我可以通过尝试制作 3D Tron Light-cycle 游戏来学习。我使用圆柱体、球体和矩形的组合制作了我的玩家载具,如下所示:
我在拉长的球体上使用了刚体,并使用了以下代码:
public float accel = 1.0f;
// Use this for initialization
void Start () {
cycleSphere = GetComponent<Rigidbody>();
}
void FixedUpdate () {
cycleSphere.velocity = Vector3.forward * accel;
}
使车辆向前移动。我不确定是否有更好的方法来做到这一点,但如果有,请告诉我。
我已将主摄像头安装到车辆上,并禁用 X 旋转以防止它和摄像头滚动。
现在我想通过按 A 和 D 按钮让它转动。与原始 Tron 轻型自行车的 90 度转向不同,我希望它像普通车辆一样转向。
所以我尝试了这个:
void Update () {
if (Input.GetKey (KeyCode.A)) {
turning = true;
turnAnglePerFixedUpdate -= turnRateAngle;
} else if (Input.GetKey (KeyCode.D)) {
turning = true;
turnAnglePerFixedUpdate += turnRateAngle;
} else {
turning = false;
}
}
void FixedUpdate () {
float mag = cycleSphere.velocity.magnitude;
if (!turning) {
Quaternion quat = Quaternion.AngleAxis (turnAnglePerFixedUpdate, transform.up);// * transform.rotation;
cycleSphere.MoveRotation (quat);
}
cycleSphere.velocity = Vector3.forward * accel;
}
虽然上面的代码确实旋转了载具,但它仍然沿最后一个方向移动 - 它的行为更像是一个坦克炮塔。更糟糕的是,过多地按下 A 或 D 会导致它朝所需的方向旋转,过一会儿就会发疯,左右旋转,并带走相机。
我做错了什么,我该如何解决?
首先,我建议您将 Input.GetKey
更改为 Input.GetAxis
,这将在按下该键时优雅地增加或减少它的值。这将为您提供将作为速度应用的力矢量归一化的选项。然后基于该矢量,您必须调整力输入,以便 "front wheel" 将 "drag" 其余的 body 转向其他方向(左或右)。这不是理想的 "real world physics behavior" 因为前向力略大于侧向(左侧或右侧)力。
代码示例:
// member fields
float sideForceMultiplier = 1.0f;
float frontForceMultiplier = 2.0f;
Vector3 currentVeloticy = Vector3.zero;
void Update()
{
Vector3 sideForce = (sideForceMultiplier * Input.GetAxis("horizontal")) * Vector3.right;
Vector3 frontForce = frontForceMultiplier * Vector3.forward;
currentVelocity = (sideForce + fronForce).Normalize;
}
void FxedUpdate()
{
cycleSphere.velocity = currentVelocity * accel;
}