Unityには車輪の再現に適したWheelColliderというのがある。今回はこれを使って車の動きを再現してみよう。
作成
1.新規3DプロジェクトからCarを作成
地面
1.新規3DオブジェクトからCubeを作成。Floorにリネーム後Scaleを以下のように調節する。
車
1.新規CreateEmptyをしてCarにリネーム後Transformを以下のように調整する。
2.CarにAddComponentからrigidbodyを追加する。Massを1500(1.5トン)に調節する。
3.Carの子要素としてCubeを作成し、Bodyとリネームする。Transformは以下
4.Carを右クリックしてCreateEmptyして、wheelsとリネーム。transformがリセットされていることを確認する。
5.Wheelsを右クリック->CreateEmptyしてFrontRを作成。Transformを調整し、WheelColliderをAdd Componentする。(パラメータはいじらなくてよい)
6.FrontRを複製して、FrontLにリネーム。Position.xを-1に変更する。
7.FrontRとFrontLを選択した状態で複製して、それぞれのposition.zを-1にする。
8.確認。4つのwheelcolliderを選択して以下のような感じに配置されてればOKだ。
Carスクリプトの作成
それではスクリプトを作成していこう。
1.新規C#スクリプトからCar.csを以下のように作成する。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Car : MonoBehaviour {
public List<AxleInfo> axleInfos;
public float maxMotorTorque;
public float maxSteeringAngle;
public void FixedUpdate() {
float motor = maxMotorTorque * Input.GetAxis("Vertical");
float steering = maxSteeringAngle * Input.GetAxis("Horizontal");
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;
}
}
}
}
[System.Serializable]
public class AxleInfo {
public WheelCollider leftWheel;
public WheelCollider rightWheel;
public bool motor; //駆動輪か?
public bool steering; //ハンドル操作をしたときに角度が変わるか?
}
2.作成が終わったらCarにアタッチ。インスペクターを以下のように調整する。今回は後輪にmotor設定をして後輪駆動車にしてみた。
3.実行してみよう。上下矢印でアクセル、左右矢印でハンドルだ。車輪の見た目はまだ作っていないがWheelColliderによって車としての挙動をすることがわかる。
車輪の見た目
車輪の見た目がないのも奇妙なものだ。見た目を作っていこう。
1.FrontRを右クリックして子要素としてSphereを作成する。transformを調整し、SphereColliderはリムーブするか無効にする。
2.残りの車輪についても同じ処理を行い実行してみよう。車輪の見た目が加わったことにより良い感じになった。
車輪に動きを加える
これだけでも十分楽しめるが、車輪の見た目を動きに連動させていこう。Car.csを以下のように変更する。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Car : MonoBehaviour {
public List<AxleInfo> axleInfos;
public float maxMotorTorque;
public float maxSteeringAngle;
public void ApplyLocalPositionToVisuals(WheelCollider collider) {
Transform visualWheel = collider.transform.GetChild(0);
Vector3 position;
Quaternion rotation;
collider.GetWorldPose(out position, out rotation);
visualWheel.transform.position = position;
visualWheel.transform.rotation = rotation;
}
public void FixedUpdate() {
float motor = maxMotorTorque * Input.GetAxis("Vertical");
float steering = maxSteeringAngle * Input.GetAxis("Horizontal");
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;
}
ApplyLocalPositionToVisuals(axleInfo.rightWheel);
ApplyLocalPositionToVisuals(axleInfo.leftWheel);
}
}
}
[System.Serializable]
public class AxleInfo {
public WheelCollider leftWheel;
public WheelCollider rightWheel;
public bool motor; //駆動輪か?
public bool steering; //ハンドル操作をしたときに角度が変わるか?
}
(解説)
現在のホイールコライダーの向きと角度を計算して、それを子要素のtransformに反映させる処理だ。
実行してみよう。車輪が回転し、操舵角も反映されている。(テクスチャーを設定してないので車輪の回転は分かりづらいが。。。)
車輪の見た目の大きさの調整
おや、サスペンションの沈み込んだ位置で車輪の描画が行われているため、タイヤが地面にめり込み過ぎている。
これを修正しよう。4個の車輪を選択してScaleのYとZを1にする。
実行してみよう。車輪のめり込みがなくなったのがわかる。
完成
これで完成だ。コースなどを作ってみるのもいいが,私はこの車をただ動かしているだけでも楽しい。バックスピンターンが決まった様子をみてもらいたい。
アセットストア
アセットストアから車体のモデルをダウンロードし、上のソースと組み合わせた。
コメント