WheelCollider(车轮碰撞器)是一种特殊的地面车辆碰撞器,它具有内置的碰撞金测、车轮物理引擎和一个基于滑移的轮胎摩擦模型。WheelCollider是专门为有轮子勺车辆所做的设计,也适用于坦克。
1.暂且把坦克当成一辆拥有四个轮子的汽车。在坦克模型下建立名为PhysicalBody的空物体(Empty Object),用于存放坦克的碰撞器组件。再在PhysicalBody里添加wheelL1、wheelR1、wheelL2和 wheelR2这4个空物体,4个wheel将代表车辆的4个轮子。在PhysicalBody里添加两个名为collider的空物体,用于给车身添加碰撞器(BoxCollider)。
2.WheelCollider),调整它们的位置和大小(通过 Wheel-图2-47Tank 的层次结构Collider组件的Radius属性调整大小),使 wheeIL1代表前方左轮,wheelR1代表前方右轮,另外两个轮子代表后方的轮子。轮子位置和角度的细微差别对物理性能的影响很大,切记,看着Transform的数值进行调整,使它们对称。
WheelCollider是用Unity3D制作汽车类型游戏的关键所在,它不仅可以模拟轮子的碰撞过程,还模拟了汽车的悬挂系统、引擎系统、轮胎摩擦等汽车的关键物理特性。WheelCollider 的一些属性如图
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Tank : MonoBehaviour
{
//炮塔炮管轮子履带
public Transform turret;
public Transform gun;
private Transform wheels;
private Transform tracks;
//炮塔旋转速度
private float turretRotSpeed = 0.5f;
//炮塔炮管目标角度
private float turretRotTarget = 0;
private float turretRollTarget = 0;
//炮管的旋转范围
private float maxRoll = 10f;
private float minRoll = -4f;
//轮轴
public List<AxleInfo> axleInfos;
//马力/最大马力
private float motor = 0;
public float maxMotorTorque;
//制动/最大制动
private float brakeTorque = 0;
public float maxBrakeTorque = 100;
//转向角/最大转向角
private float steering = 0;
public float maxSteeringAngle;
public void PlayerCtrl()
{
//只有玩家操控的塔克才会生效
if (ctrlType != CtrlType.player)
return;
//马力和转向角
motor = maxMotorTorque * Input.GetAxis("Vertical");
steering = maxSteeringAngle * Input.GetAxis("Horizontal");
//制动
brakeTorque = 0;
foreach (AxleInfo axleInfo in axleInfos)
{
if (axleInfo.leftWheel.rpm > 5 && motor < 0) //前进时,按下“下”键
brakeTorque = maxBrakeTorque;
else if (axleInfo.leftWheel.rpm < -5 && motor > 0) //后退时,按下“上”键
brakeTorque = maxBrakeTorque;
continue;
}
}
//轮子旋转
public void WheelsRotation(WheelCollider collider)
{
if (wheels == null)
return;
//获取旋转信息
Vector3 position;
Quaternion rotation;
collider.GetWorldPose(out position, out rotation);
//旋转每个轮子
foreach (Transform wheel in wheels)
{
wheel.rotation = rotation;
}
}
//履带滚动
public void TrackMove()
{
if (tracks == null)
return;
float offset = 0;
if (wheels.GetChild(0) != null)
offset = wheels.GetChild(0).localEulerAngles.x / 90f;
foreach (Transform track in tracks)
{
MeshRenderer mr = track.gameObject.GetComponent<MeshRenderer>();
if (mr == null) continue;
Material mtl = mr.material;
mtl.mainTextureOffset = new Vector2(0, offset);
}
}
void Start()
{
//获取炮塔
turret = transform.Find("turret");
//获取炮管
gun = turret.Find("gun");
//获取轮子
wheels = transform.Find("wheels");
//获取履带
tracks = transform.Find("tracks");
}
//每帧执行一次
void Update()
{
//玩家控制操控
PlayerCtrl();
//遍历车轴
foreach (AxleInfo axleInfo in axleInfos)
{
//转向(前轮控制方向)
if (axleInfo.steering)
{
axleInfo.leftWheel.steerAngle = steering;
axleInfo.rightWheel.steerAngle = steering;
}
//马力(后轮提供马力)
if (axleInfo.motor)
{
axleInfo.leftWheel.motorTorque = motor;
axleInfo.rightWheel.motorTorque = motor;
}
//制动
if (true)
{
axleInfo.leftWheel.brakeTorque = brakeTorque;
axleInfo.rightWheel.brakeTorque = brakeTorque;
}
//转动轮子履带
if (axleInfos[1] != null && axleInfo == axleInfos[1])
{
WheelsRotation(axleInfos[1].leftWheel);
TrackMove();
}
}
}
using UnityEngine;
[System.Serializable]
public class AxleInfo
{
public WheelCollider leftWheel;
public WheelCollider rightWheel;
public bool motor;//动力
public bool steering;//方向
}