Version: 2019.1
ジョイントとラグドールの安定性
スクリプト

Wheel Collider チュートリアル

Wheel Collider コンポーネントは PhysX3 Vehicles SDK によって強化されています。

このチュートリアルでは、基本的な機能をもつ車を作成してみましょう。

まず初めに GameObject > 3D Object > Plane の順に選択してください。これは車が走る地面です。わかりやすくするために、地面の Transform を 0 にします (インスペクターウィンドウの Transform コンポーネントで、設定の歯車アイコンをクリックし Reset を選択)。Transform の Scale を 100 にして地面を拡大します。

基本的な車のスケルトンの作成

  1. まず、車のルートゲームオブジェクトになるゲームオブジェクトを作成します。 GameObject > Create Empty と選択し、ゲームオブジェクトの名前を car_root に変更します。
  2. Physics 3D Rigidbody コンポーネントを car_root に加えます。デフォルトで設定されている Mass (質量) 1kg では、デフォルトのサスペンション設定には軽すぎるので、1500kg に変更してずっと重くします。
  3. 次に、車体のコライダーを作成します。 GameObject > 3D Object > Cube を選択してください。作成したキューブを car_root の子のゲームオブジェクトにします。ローカル座標空間で完全に整列させるために、トランスフォームを 0 にリセットします。車は Z 軸に合わせて配置されているので、Transform の ScaleZ を 3 に設定します。
  4. ホイールをルートに加えます。car_root を選択しておき GameObject > Create Empty Child を選択します。名前を wheels に変更します。Transform をリセットしてください。このゲームオブジェクトは強制ではありませんが、後で調節やデバッグを行うのに便利です。
  5. 最初のホイールを作成します。wheels ゲームオブジェクトを選択しておいて GameObject > Create Empty Child の順に選び、名前を frontLeft にします。Transform の PositionX を –1、Y を 0、Z を 1 に設定します。ホイールにコライダーを設定するには Add component > Physics > Wheel Collider の順に選択します。
  6. frontLeft ゲームオブジェクトを複製します。 Transform の Position の X を 1 に変更し、名前を frontRight に変更します。
  7. frontLeftfrontRight オブジェクトの両方を選択します。それらを複製し、両方の Transform の Position の Z を −1 に変更します。それぞれ名前を rearLeftrearRight に変更します。
  8. 最後に、car_root ゲームオブジェクトを選択し、移動ツールを使用して、それを地面の少し上に上げます。

これで、下の図ように見えるはずです。

この車を実際に動かすにはコントローラーを作成する必要があります。下のコードサンプルはコントローラーとして使えます。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
    
public class SimpleCarController : 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; // このホイールがハンドルの角度を反映しているかどうか
}

car_root ゲームオブジェクト上で新しい C# スクリプトを作成し (Add Component > New Script)、このコード例をスクリプトにコピーし、 SimpleCarController.cs で保存します。スクリプトのパラメーターを以下のように微調整できます。設定をテストするには再生モードで試してみます。

以下の設定は車のコントローラーとしてとても効果的です。

1 台の車に最大 20 のホイールを設定することができ、それぞれにハンドル、エンジン、ブレーキのトルクを適用できます。

今度は、視覚的なホイールに移ります。ご覧のとおり、Wheel Collider はシミュレーションしたホイール位置と回転を Wheel Collider の Transform には適用しません。そのため、視覚的なホイールを追加するには、いくらか工夫が必要です。

まず、いくつかホイールジオメトリを作らなくてはなりません。シリンダーから簡単なホイール形状を作れます。視覚的なホイールを追加するにはいくつか方法があります。スクリプトプロパティーで、手動で視覚的なホイールを割り当てるか、または、いくつかのロジックを書いて、自動的に対応する視覚的なホイールを検索します。私たちは、2 番目の方法を使用します。Wheel Collider ゲームオブジェクトに、視覚的なホイールを付加します。

コントローラースクリプトを変更します。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[System.Serializable]
public class AxleInfo {
    public WheelCollider leftWheel;
    public WheelCollider rightWheel;
    public bool motor;
    public bool steering;
}
     
public class SimpleCarController : MonoBehaviour {
    public List<AxleInfo> axleInfos; 
    public float maxMotorTorque;
    public float maxSteeringAngle;
     
    // 対応する視覚的なホイールを見つけます
    // Transform を正しく適用します
    public void ApplyLocalPositionToVisuals(WheelCollider collider)
    {
        if (collider.transform.childCount == 0) {
            return;
        }
     
        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.leftWheel);
            ApplyLocalPositionToVisuals(axleInfo.rightWheel);
        }
    }
}

Wheel Collider コンポーネントのうち大切なパラメーターの 1 つは Force App Point Distance です。これは、ホイールの基準となる静止位置からホイールの力が適用される位置までの距離を示します。デフォルト値は 0 、つまり、ホイールの基準となる静止位置に力を適用します。しかし、実際は車の重心より少し下にこの位置を置くとよいでしょう。

ノート: 実際の Wheel Collider の動きを見るには、Vehicle Tools をダウンロードします。このパッケージには、ホイール付きの車を装備し wheel collider のサスペンションを作成するツールが含まれています。


ジョイントとラグドールの安定性
スクリプト