前言

先前有介紹過使用插件可以快速地讓所創立的車子跑起來,有興趣的可以看一下先前的Easy Suspension – Make car move in Unity ,雖然這個方法非常簡單也好上手,但是插件語法的缺點是用在Game play的情況下才會看到車輪,那如果我們想要真的要讓車子跑起來的話還是需要用到Wheel collider才是正確的流程,今天就是要利用C#的創建讓車子向真實世界一樣的跑起來。
在開始之前我們需要一輛車子,或許大家都有自己製作或是用過的車子模型,如果沒有的朋友可以從下面的連結下載免費的汽車模型。
Car Model: https://assetstore.unity.com/packages…
- 將模型匯入Unity Asset , 並依照自己的喜好設定環境跟 Volume等等,因為設定環境跟Volume或是Post-processing不是本篇重點,這邊就不贅述了。

2. 將車子跟要試跑的環境建立好以後我們就可以開始一些基本的設定,因為汽車的碰撞偵測需要Rigibody跟Collider,如果想要更加了解Rigibody跟Collider之間的關係可以參考蛋哥之前所寫的Simulator Scene in Unity3D – Collider and Rigidbody 3D version (Section 1) ,這邊汽車的Collider可以使用Mesh Collider或是Box Collider ,如果是要依照真實世界的碰撞建議還是要用Mesh Collider製作汽車模型的外型Collider。

設定好Collider以及Rigibody以後我們按下Game play看看是否有建立成功

2. 接著我們就要開始建立今天的重點- WheelCollider了
Mass : 輪軸物件的質量。
Radius : 輪軸碰撞器的半徑。
Wheel Damping Rate : 避震器,避震值範圍。
Suspension Distance : 車輪懸架的最大延伸距離,從輪軸中心Y軸向下延伸。 數值越大距離越遠。
Force App Point Distance : 施力點距離 ,預設為0,最好把這個值調整到wheel Collider邊界上。
Center : 輪軸中心離地板的距離。

Suspension Spring : 這邊是更細部設定碰撞器的輪軸避震值的細部設定。懸架試圖達到目標位置,通過增加彈簧和阻尼力。
Spring : 彈力試圖到達目標位置。較大的值可使懸架更快地到達目標位置。 值介於 0 – 無限。
Damper : 降低懸架速度。較大的值會使懸架彈簧的移動速度變慢。 值介於 0 – 無限。
Target Position : 懸架沿懸架距離的靜止距離。 1映射到完全擴展的懸架,0映射到完全壓縮的懸架。默認值為0.5,與常規汽車的懸架狀態一致。
Forward Friction / Sideway Friction:車輪向前和向側面滾動時輪胎的摩擦特性。
在摩擦力的調整,可以說是在調整你輪胎的橡膠的摩擦係數,Extremum Slip / Value:在調整輪胎運動向前與向側邊的摩擦係數,值越高越滑。此參數會跟著加速度的曲線成正比,煞車亦同。Asymptote Slip / Value:曲線的結束點,此參數會與Extremum會同時運算會製成Curve圖(如下圖),當車輛行徑力道與滑動係數會將上方兩個值做即時運算。

這邊可以直接複製原本的車輪物件貼上,這樣就不用一個一個調整WheelCollider的位置,如果位置有跑掉的話還是要打開Mesh Render對齊輪胎的實際位置,這邊輪胎的數值可以提供給大家參考。
Mass: 100
Radius: 0.38
Wheel Damping Rate: 1
Suspension Distance: 0.38
Force App Point Distance:0

3. 設定好WheelCollider以後我們就要利用C#讓輪子動起來,首先我們在Script點選右鍵建立新的C#檔案,並記得命名為自己習慣的控制器名字

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CarControllerEddie1 : MonoBehaviour
{
//Axis的設定
public void GetInput()
{
m_horizontalInput = Input.GetAxis("Horizontal");
m_verticalInput = Input.GetAxis("Vertical");
}
//轉向設定
private void Steer()
{
m_steeringAngles = maxSteerAngle * m_horizontalInput;
frontDriverW.steerAngle = m_steeringAngles;
frontPassengerW.steerAngle = m_steeringAngles;
}
//設定加速度
private void Accelerate()
{
frontDriverW.motorTorque = m_verticalInput * motorForce;
frontPassengerW.motorTorque = m_verticalInput * motorForce;
}
//設定車輪的Transform以及WheelCollider的Pose
private void UpdateWheelPoses()
{
UpdateWheelPose(frontDriverW, frontDriverT);
UpdateWheelPose(frontPassengerW, frontPassengerT);
UpdateWheelPose(rearDriverW, rearDiverT);
UpdateWheelPose(rearPassengerW, rearPassengerT);
}
private void UpdateWheelPose(WheelCollider _collider, Transform _transform)
{
Vector3 _pos = _transform.position;
Quaternion _quat = _transform.rotation;
_collider.GetWorldPose(out _pos, out _quat);
_transform.position = _pos;
_transform.rotation = _quat;
}
private void FixedUpdate()
{
GetInput();
Steer();
Accelerate();
UpdateWheelPoses();
}
private float m_horizontalInput;
private float m_verticalInput;
private float m_steeringAngles;
public WheelCollider frontDriverW, frontPassengerW;
public WheelCollider rearDriverW, rearPassengerW;
public Transform frontDriverT, frontPassengerT;
public Transform rearDiverT, rearPassengerT;
//預設最大輪胎轉向角度以及動力
public float maxSteerAngle = 30;
public float motorForce = 50;
}
建立好我們的車輪控制器以後我們在汽車模型的Inspector裡按下Add Componemt選取剛剛所建立好的語法檔案,這時候就可以看到我們在與法理面設定好的Wheel Collider以及 Transform選項可以使用了。

接著我們依照所建立好的WheelCollider以及Transform相對名字拖曳擺放即可

直接按下Game play測試一下,看到起來前進倒退都是沒有什麼問題的,目前我們已經完成了9成了,只差攝影機的設定就完成了。

一樣的我們點選右鍵新建一個新的C#檔案命名為CameraFollower

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamerFollowController : MonoBehaviour
{
public void LookAtTarget()
{
Vector3 _LookDirection = objectToFollow.position - transform.position;
Quaternion _rot = Quaternion.LookRotation(_LookDirection, Vector3.up);
transform.rotation = Quaternion.Lerp(transform.rotation, _rot, lookSpeed * Time.deltaTime);
}
public void MoveTotarget()
{
Vector3 _targetPos = objectToFollow.position +
objectToFollow.forward * offset.z +
objectToFollow.up * offset.y;
transform.position = Vector3.Lerp(transform.position, _targetPos, followSpeed * Time.deltaTime);
}
public void FixedUpdate()
{
LookAtTarget();
MoveTotarget();
}
public Transform objectToFollow;
public Vector3 offset;
// 設定跟隨速度
public float followSpeed = 10;
public float lookSpeed = 10;
}
然後我們就可以將所要跟隨的物件拖曳到Object to follow的項目內就完成攝影機的跟隨了

可是按下Play以後我們可以馬上就發現問題了! 攝影機的位置在車底下是不合理的

不用緊張,因為我們在語法裡面有設定到Camera的Offset位置可以調整,依照自己想要的方式需求調整攝影機就可以看到攝影機跟隨車子的畫面看起來舒服多了。


小記
學習C#來控制Unity裡面的物件是一個相當有趣的事情,雖然對於C#語法並不是太熟悉但是多學習多練習總會找到一套方法的,這次的練習雖然網路上有相當多的插件或是有許多已經寫好的控制器語法可供下載,但是自己下去練習做一次才是學習的真諦。
參考資料:https://www.youtube.com/watch?v=uSr5IfzclP8&t=861s