製作地形
2019版
2018版
賽車
車輪
尾燈
代碼:CarController
public class CarController : MonoBehaviour {
//拿到車輪碰撞器。
public WheelCollider[] WheelCollider;
//拿到車輪。寫完這兩個程序,需要到unity裏關聯一下。
public Transform[] WheelTrans;
//是否在剎車,保存剎車狀態
private bool isBreak;
//聲音播放器
AudioSource player;
//拿到後面的燈。寫完這個程序,需要到unity裏關聯一下。
public GameObject[] BackLight;
// Use this for initialization
void Start () {
//在這裏獲取聲音播放器
player = GetComponent<AudioSource>();
//調整車輛重心(只能調一次。就是調剛體的重心)
GetComponent<Rigidbody>().centerOfMass = new Vector3(0, 0, 0);
}
// Update is called once per frame
void Update () {
//得到軸:垂直軸、水平軸
float vertical = Input.GetAxis("Vertical");
float horizontal = Input.GetAxis("Horizontal");
/*前進。此處是後輪驅動,所以要拿到後輪。
motorTorque扭矩,它的數值越大,轉的越快。此時轉的是碰撞器。*/
WheelCollider[2].motorTorque = vertical * 300;
WheelCollider[3].motorTorque = vertical * 300;
//轉向。是對前輪做操作。steerAngle旋轉。此處最大爲50度
WheelCollider[0].steerAngle = horizontal * 50;
WheelCollider[1].steerAngle = horizontal * 50;
//遍歷四個輪胎,讓輪胎同步車輪碰撞器
for (int i = 0; i < WheelCollider.Length; i++)
{
//獲取車輪碰撞器的位置和旋轉
Vector3 pos;
Quaternion rotation;
WheelCollider[i].GetWorldPose(out pos, out rotation);
/*GetWorldpose在當前世界座標裏的姿態,其實就是獲得它的兩個參數:位置和旋轉。
都用out自動調整兩個參數的值,此時獲得了碰撞器的數值,下面賦值給輪胎。*/
WheelTrans[i].position = pos;
WheelTrans[i].rotation = rotation;
}
//轉速錶(關係到聲音)。拿任意一個驅動輪即可
Debug.Log(WheelCollider[2].rpm);
//剎車
if(Input.GetKeyDown(KeyCode.Space))
{
isBreak = true;
//剎車的力(要大於上面所給的驅動力)。此處前輪剎車+後輪剎車
WheelCollider[0].brakeTorque = 1000;
WheelCollider[1].brakeTorque = 1000;
WheelCollider[2].brakeTorque = 500;
WheelCollider[3].brakeTorque = 500;
//亮後燈
BackLight[0].SetActive(true);
BackLight[1].SetActive(true);
}
if(Input.GetKeyUp(KeyCode.Space))
{
isBreak = false;
//不是剎車狀態時,這個剎車的力爲0。
WheelCollider[0].brakeTorque = 0;
WheelCollider[1].brakeTorque = 0;
WheelCollider[2].brakeTorque = 0;
WheelCollider[3].brakeTorque = 0;
//關掉後燈
BackLight[0].SetActive(false);
BackLight[1].SetActive(false);
}
/*播放聲音。Mathf.Clamp01限制在0-1。
拿到一個輪胎的轉速WheelCollider[2].rpm,假設它3000是最大值。*/
//當轉速爲最大值時,聲音值爲1(正常)。
player.pitch = Mathf.Clamp01(WheelCollider[2].rpm / 3000);
//當按了後退鍵,亮後燈
if(vertical < 0)
{
//亮後燈
BackLight[0].SetActive(true);
BackLight[1].SetActive(true);
}
else if(vertical > 0 && isBreak == false)
{
//關掉後燈
BackLight[0].SetActive(false);
BackLight[1].SetActive(false);
}
}
}
攝像機跟隨
系統給了很多跟隨腳本。此處的跟隨方法,只適合看着玩家背部前進的。
法一相對一法二來說,視野裏的汽車更爲豐富。因爲,法二的相機是不旋轉的,看到的汽車部位是不變的;而法一是平滑跟隨,攝像機的前方和汽車的前方是逐漸一致的,所以當汽車進行轉彎的時候,可以看到汽車的側身。
法一:平滑跟隨
public class FlowTarget : MonoBehaviour {
//跟隨的目標
public Transform target;
//跟隨的高度
public float height;
//跟隨的距離
public float distance;
void Start () {
}
//兩個更新的方法:Update和LateUpdate。 把Update改爲LateUpdate
//物體移動是在Update裏面做的,攝像機是跟隨物體移動,所以在LateUpdate裏面。
void LateUpdate () {
//法一:平滑跟隨。我的前方和目標的前方逐漸一致,利用插值。
//注意這種跟隨是不需要對Y軸進行差值的,所以要把攝像機的Y軸清空置爲0。
Vector3 forward = transform.forward;
forward.y = 0;
//我的前方和目標的前方是逐漸一致,所以用到差值。1 也可以寫成一個變量,在unity中進行調節。* Time.deltaTime爲了使各設備一致
//Vector3 newForward = Vector3.Lerp(transform.forward, target.forward, 1 * Time.deltaTime); 此時,攝像機拍攝車頂。需要設定Y軸。
Vector3 newForward = Vector3.Lerp(forward, target.forward, 1 * Time.deltaTime);
//攝像機的位置。1>將原本的target.forward * distance修改爲newForward * distance
transform.position = target.position - newForward * distance + Vector3.up * height;
//只寫上面那句,沒有這句的話,相機不會發生旋轉,會有車輛駛出屏幕的情況。
transform.LookAt(target);
}
}
法二:普通跟隨
public class FlowTarget : MonoBehaviour {
void LateUpdate () {
//法一:平滑跟隨。我的前方和目標的前方逐漸一致,利用插值。
//法二:跟隨。
//攝像機的位置。target.forward * distance是個正數,那麼減掉它,確保攝像機在物體的後方。
//*distance、*height就是和之前*2都一樣,只不過這裏不知道具體乘以多少,需要到unity裏調節得到。
transform.position = target.position - target.forward * distance + Vector3.up * height;
//只寫上面那句,沒有這句的話,相機不會發生旋轉,會有車輛駛出屏幕的情況。
transform.LookAt(target);
}
}