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

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 に設定して Z 軸方向に拡大します。
  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; // the information about each individual axle
        public float maxMotorTorque; // maximum torque the motor can apply to wheel
        public float maxSteeringAngle; // maximum steer angle the wheel can have
        
        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; // is this wheel attached to motor?
        public bool steering; // does this wheel apply steer angle?
    }

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;
     
        // finds the corresponding visual wheel
        // correctly applies the 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 のサスペンションを作成するツールが含まれています。


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