JointとRagdollの安定性
スクリプト

WheelCollider チュートリアル

PhysX3 Vehicles SDKによって WheelCollider が強化され新しくなりました、PhysX2の頃と比較しても全く新しい車両シミュレーションライブラリとなっています。

それでは Unity5.0 で基本要素をおさえた、動く車を作成してみましょう。

まず初めに GameObject -> 3D Object -> Plane と選択してください。これは車を運転するための地面です。地面は単純にTransform の Position 値をゼロ(Transform -> Reset)にして作成します。Transform の Scale を100ぐらいに大きくして設置しましょう。

基本的な車のスケルトンを作成します。

1.まず、車のルートオブジェクトになるゲームオブジェクトを追加します: GameObject -> Create Empty と選択し、名前を car_root に変更します。

  1. Physics 3D Rigidbody コンポーネントを car_root に追加してください。デフォルトで設定されている質量 1kg では、デフォルトのサスペンション設定には軽すぎるので、 1500kg に変更してください。

  2. 次に、カーボディーコライダーを作成します: GameObject -> 3D Object -> Cube を選択してください。 car_root の下に、そのボックスを親子付けします。ローカル座標空間にぴったり配置するために、トランスフォームをリセットします。車をZ軸方向に向けたいので、ボックスのzのスケーリング値を3に設定して、Z軸方向に拡大します。

  3. ホイールルートを追加します。car_root を選択し GameObject -> Create Empty Child を表示します。名前を wheels に変更します。トランスフォームを初期化してください。このノードは強制ではありませんが、後で改良するのに便利です。

  4. 最初のホイールの作成。wheels オブジェクトを選択して、GameObject -> Create Empty Child、名前を frontLeft にします。トランスフォームをリセットしてください。ポジションを(–1, 0, 1)に設定してください。ホイールに Physics component -> wheel collider で追加してください。

  5. frontLeft オブジェクト(CMD-DまたはControl-D)を複製します。x のポジションを1に変更してください。名前を frontRight に変更してください。

  6. frontLeftfrontRight オブジェクトの両方を選択します。それらを複製します。両方の z ポジションを−1に変更してください。それぞれ名前を rearLeftrearRight に変更してください。

  7. 最後に、car_root オブジェクトを選択し、トランスフォームマニピュレータを使用して、それを地面の少し上に上げます。

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

 ![](../uploads/Main/WheelColliderTutorial.png) 

この車を実際に動かすにはコントローラを記述する必要があります。それでは、いくつかのスクリプトを見てみましょう。

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 オブジェクトに設定し、スクリプトパラメータを以下のように調整するだけで、プレイモードを開始できます。設定をいろいろ変えてみてください。以下に表示したものは、まあまあ良く動くようです。

車両のインスタンスには 1 台につき車輪を 20 個まで追加する事が可能で、車輪毎に steering、motor、braking torque を設定できます。

今度は視覚的な車輪に移ります。見たとおり、WheelCollider はシミュレートされたホイール位置と WheelCollider のトランスフォームの後ろ回転には適用しません。そのため、視覚的なホイールを追加するには、いくつかのトリックが必要です。

  1. まず、いくつかホイールジオメトリを作らなくてはなりません。シリンダーから簡単なホイール形状を作ることが可能です。

  2. 視覚的なホイールを追加するいくつかの方法が存在します。そのためには、スクリプトのプロパティーで、手動で視覚的なホイールを割り当てるか、または、いくつかのロジックを書いて、自動的に対応する視覚ホイールを検索する必要があります。私たちは、第 2 のアプローチを取ります。

  3. ホイールコライダーオブジェクトに、表示用の車輪を付加します。

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

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);
        }
    }
}
        

WheelCollider コンポーネントにとって重要なパラメータの 1 つは forceAppPointDistance です。これは、静止ホイールのベースからホイールの力が適用される点までの距離のことを言います。デフォルト値は0で静止ホイールの基準の力であることを意味しますが、この点は、実際には、ひとかたまりの車の中心部の少し下のどこかに位置しているのが賢明です。

JointとRagdollの安定性
スクリプト