很多游戏中有着像汽车等交通工具,在Unity内置的物理引擎可以帮助开发者进行设计开发。在Unity中通过车轮碰撞器来控制车轮运动,以实现车轮带动汽车行驶的效果。
车轮碰撞器的添加方法与其他碰撞器的添加方法不同,车轮碰撞器一般不直接添加到车轮游戏对象上,而是添加交通工具游戏对象的子对象目录中新建的空对象上,然后将此空对象的位置调整到与车轮位置相同。
车轮的重力
车轮的半径
车轮旋转阻尼
悬挂高度,可提高车辆稳定性,不小于0且方向垂直向下
悬挂力应用点
基于模型坐标系的车轮碰撞器的中心点
达到目标中心的弹力,值越大到达中心越快
悬浮速度的阻尼,值越大车辆归位所消耗的时间越长
悬挂中心
摩擦曲线滑动极值
摩擦曲线的极值点
渐进线的滑动值
曲线的渐进线点
刚度,控制侧向摩擦曲线的倍数


F1为空对象
Wheel为空对象
WheelCollider为空对象



Car.cs 将脚本挂载在F1上,通过摇杆来控制汽车
public class Car : MonoBehaviour {
public WheelCollider FLCollider;//声明车前左侧车轮碰撞器
public WheelCollider FRCollider;//声明车前右侧车轮碰撞器
public EasyJoystick myJoystick;//声明虚拟摇杆
public float maxTorque = 500;//初始化最大力矩
public float maxAngle = 20;//初始化最大旋转角
void Start()
{
GetComponent<Rigidbody>().centerOfMass = new Vector3(0, -0.8f, 0);//赛车刚体重心
}
void FixedUpdate()
{
FLCollider.motorTorque = maxTorque * myJoystick.JoystickTouch.y;//控制力矩
FLCollider.steerAngle = maxAngle * myJoystick.JoystickTouch.x;//控制旋转角
FRCollider.motorTorque = maxTorque * myJoystick.JoystickTouch.y;//控制力矩
FRCollider.steerAngle = maxAngle * myJoystick.JoystickTouch.x;//控制旋转角
}
}
Wheel.cs 该脚本根据车轮碰撞器在行驶过程中和转弯过程中发生的旋转,使车轮游戏对象与车轮碰撞器同步
public class Wheel : MonoBehaviour {
public WheelCollider CPCollider;//声明对应的车轮碰撞器
public float CirValue = 0;//声明车轮滚动角
void Update()
{
transform.rotation = CPCollider.transform.rotation * Quaternion.Euler(CirValue, CPCollider.steerAngle, 0);//旋转车轮
CirValue += CPCollider.rpm * 360 / 60 * Time.deltaTime;//计算车轮滚动角
}
}
SmoothFollow.cs 使摄像机按照一定的距离和高度跟随赛车游戏对象F1同步运动
public class SmoothFollow : MonoBehaviour {
public float distance = 10.0f;//声明跟随距离
public float height = 5.0f;//声明跟随高度
public float heightDamping = 2.0f;//声明高度阻尼
public float rotationDamping = 3.0f;//声明角度阻尼
public float offsetHeight = 1.0f;//声明高度偏移量
Transform selfTransform;
public Transform Target;//声明对象
[AddComponentMenu("Camera-Control/Smooth Follow")]//在功能列表中添加功能选项
void Start()
{
selfTransform = GetComponent<Transform>();
}
void LateUpdate()
{
if (!Target)
return;
float wantedRotationAngle = Target.eulerAngles.y;//预设角度
float wantedHeight = Target.position.y + height;//预设高度
float currentRotationAngle = selfTransform.eulerAngles.y;//当前角度
float currentHeight = selfTransform.position.y;//当前高度
currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);//角度渐变至预设角度
currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);//高度渐变至预设高度
Quaternion currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);
selfTransform.position = Target.position;//位置调整
selfTransform.position -= currentRotation * Vector3.forward * distance;
Vector3 currentPostion = transform.position;
currentPostion.y = currentHeight;
selfTransform.position = currentPostion;
selfTransform.LookAt(Target.position + new Vector3(0, offsetHeight, 0));//设置摄像机正对中心
}
}