Vehicles (modeling)
January 2024
車(モデリング)
物理モデル
どんな乗り物にも物理衝突モデルが必要です。以下のようなセクションがqcファイルに必要になります。(物理モデルの作成については衝突モデル を参考にしてください。)
$collisionmodel "digger_physbox.smd" { // Mass in kilograms $Mass 1600 }
手始めとしては、乗り物の表示モデルから車輪を除いたものを使うことができます。その場合、実際の衝突モデルは表示モデルを囲む凸包になります。この衝突モデルはマップに配置してコンソールから"vcollide_wireframe 1"
を入力することで可視化することができます。
車輪の衝突設定
次に、車輪の設定をします。最良の結果を得るには、.QCファイルでそれぞれの車輪のAttachmentポイントを配置するのがよいでしょう。
$attachment wheel_fl "Dummy04" 0 0 8 $attachment wheel_fr "Dummy03" 0 0 -8 $attachment wheel_rl "Dummy01" 0 0 8 $attachment wheel_rr "Dummy02" 0 0 -8
現時点では四輪がサポートされています。2文字のコードを使って名前がつけられています:fl "front left"(左前輪)、fr "front right"(右前輪)、rl "rear left"(左後輪)、rr "rear right"(右後輪)です。Attachmentの名前は上と同じにする必要があります。ただ、qcファイルの記述の順番は変えても構いません。
重要な点の一つは、車輪は球体モデルとして扱われるということです。この理由で、車輪を乗り物の下に少し引き込みました。車輪ボーンの原点は実際は表示される車輪の中心になっていますが、球体の車輪が車の下から出ること(そして車の横のものをこすること)を避けるために、それぞれのAttachmentを少し引き込みました。
例: 以下の設定だと表示モデルと同じ位置に車輪を配置します:
$attachment wheel_fl "Dummy04" 0 0 0
以下は8インチだけ調整しています:
$attachment wheel_fl "Dummy04" 0 0 8
どのくらい引き込むのがよいのかは、車輪のサイズと車の衝突モデルによります。この場合では、半径約22.5インチの車輪で、8インチ引き込みました。最初はこの比率を使ってみるのがよいでしょう。乗り物をprop_vehicle
として配置したマップを作ると、コンソールから"ent_bbox prop_vehicle"
を入力して車輪を可視化することができます。
乗り物アニメーション
乗り物には必須のアニメーションが数個あります。
- 車輪のステアリングのシークエンス。もし望むなら3フレームだけ(左、中央、右)だけでもかまいません。車輪の角度を記録して、一貫性があるようにします。その値を乗り物のスクリプトファイルに入れることで物理とアニメーションが一致するようにします。
- サスペンションの動きのシークエンス。2フレームだけ(完全に圧縮した状態と、伸びた状態)でも大丈夫です。このシークエンスがそれぞれの車輪がどれだけ移動したかを決定します。車を傾けたり持ち上がった状態にしたいなら、後輪のサスペンションが前輪より伸びるようにする必要があるでしょう。
- 全ての車輪が回転しているシークエンス
ステアリング、サスペンション、車輪の回転は全てアニメーションであり、どんなものに対応付けを行うこともできます。砂漠のバギーのサスペンションも、車輪の逆回転もアニメーションflexとすることができます。物理システムでこれらのシミュレーションを行うわけでばありませんが、しかしシミュレーションと正確に協調して動くため、シミュレーションを行っているように見えるでしょう。シミュレーションとアニメーションの対応付けを行うために以下のポーズパラメータが必要です。
以下がステアリングをコントロールします。-1が左、+1は右です。
$poseparameter "vehicle_steer" -1 1
以下は車輪の高さをコントロールします(サスペンションのアニメーションをFlexで動かします)。0が圧縮、1が伸びた状態です。
$poseparameter "vehicle_wheel_fl_height" 0 1 $poseparameter "vehicle_wheel_fr_height" 0 1 $poseparameter "vehicle_wheel_rl_height" 0 1 $poseparameter "vehicle_wheel_rr_height" 0 1
以下はそれぞれの車輪の回転をコントロールします。初期・ベースの回転状態からプラスマイナス180度回ります。
$poseparameter "vehicle_wheel_fl_spin" -180 180 wrap $poseparameter "vehicle_wheel_fr_spin" -180 180 wrap $poseparameter "vehicle_wheel_rl_spin" -180 180 wrap $poseparameter "vehicle_wheel_rr_spin" -180 180 wrap
以下がポーズパラメータを設定するqcファイルの例です。
$animation neutral "digger_idle" frames 0 0 $weightlist front_wheels { "Dummy03" 1.0 "Dummy04" 1.0 } $animation turn_left "digger_turn" frame 0 0 subtract neutral 0 weightlist front_wheels $animation turn_right "digger_turn" frame 2 2 subtract neutral 0 weightlist front_wheels $sequence turning { turn_left turn_right blend vehicle_steer -1 1 } weightlist front_wheels delta autoplay // front right $weightlist wheel_fr { "Dummy03" 1.0 } $animation wheel_fr_low "digger_suspension" frame 0 0 subtract neutral 0 weightlist wheel_fr $animation wheel_fr_high "digger_suspension" frame 2 2 subtract neutral 0 weightlist wheel_fr $sequence wheel_fr_suspension { wheel_fr_low wheel_fr_high blend "vehicle_wheel_fr_height" 0 1.0 } weightlist wheel_fr delta autoplay $animation wheel_fr_spin0 "digger_wheelspin" frame 0 0 subtract neutral 0 weightlist wheel_fr $animation wheel_fr_spin120 "digger_wheelspin" frame 3 3 subtract neutral 0 weightlist wheel_fr $animation wheel_fr_spin240 "digger_wheelspin" frame 6 6 subtract neutral 0 weightlist wheel_fr $sequence wheel_fr_spin { wheel_fr_spin0 wheel_fr_spin120 wheel_fr_spin240 wheel_fr_spin0 blendwidth 4 blend "vehicle_wheel_fr_spin" -180 180 } weightlist wheel_fr delta autoplay // front left $weightlist wheel_fl { "Dummy04" 1.0 } $animation wheel_fl_low "digger_suspension" frame 0 0 subtract neutral 0 weightlist wheel_fl $animation wheel_fl_high "digger_suspension" frame 2 2 subtract neutral 0 weightlist wheel_fl $sequence wheel_fl_suspension { wheel_fl_low wheel_fl_high blend "vehicle_wheel_fl_height" 0 1.0 } weightlist wheel_fl delta autoplay $animation wheel_fl_spin0 "digger_wheelspin" frame 0 0 subtract neutral 0 weightlist wheel_fl $animation wheel_fl_spin120 "digger_wheelspin" frame 3 3 subtract neutral 0 weightlist wheel_fl $animation wheel_fl_spin240 "digger_wheelspin" frame 6 6 subtract neutral 0 weightlist wheel_fl $sequence wheel_fl_spin { wheel_fl_spin0 wheel_fl_spin120 wheel_fl_spin240 wheel_fl_spin0 blendwidth 4 blend "vehicle_wheel_fl_spin" -180 180 } weightlist wheel_fl delta autoplay // rear right $weightlist wheel_rr { "Dummy02" 1.0 } $animation wheel_rr_low "digger_suspension" frame 0 0 subtract neutral 0 weightlist wheel_rr $animation wheel_rr_high "digger_suspension" frame 2 2 subtract neutral 0 weightlist wheel_rr $sequence wheel_rr_suspension { wheel_rr_low wheel_rr_high blend "vehicle_wheel_rr_height" 0 1.0 } weightlist wheel_rr delta autoplay $animation wheel_rr_spin0 "digger_wheelspin" frame 0 0 subtract neutral 0 weightlist wheel_rr $animation wheel_rr_spin120 "digger_wheelspin" frame 3 3 subtract neutral 0 weightlist wheel_rr $animation wheel_rr_spin240 "digger_wheelspin" frame 6 6 subtract neutral 0 weightlist wheel_rr $sequence wheel_rr_spin { wheel_rr_spin0 wheel_rr_spin120 wheel_rr_spin240 wheel_rr_spin0 blendwidth 4 blend "vehicle_wheel_rr_spin" -180 180 } weightlist wheel_rr delta autoplay // rear left $weightlist wheel_rl { "Dummy01" 1.0 } $animation wheel_rl_low "digger_suspension" frame 0 0 subtract neutral 0 weightlist wheel_rl $animation wheel_rl_high "digger_suspension" frame 2 2 subtract neutral 0 weightlist wheel_rl $sequence wheel_rl_suspension { wheel_rl_low wheel_rl_high blend "vehicle_wheel_rl_height" 0 1.0 } weightlist wheel_rl delta autoplay $animation wheel_rl_spin0 "digger_wheelspin" frame 0 0 subtract neutral 0 weightlist wheel_rl $animation wheel_rl_spin120 "digger_wheelspin" frame 3 3 subtract neutral 0 weightlist wheel_rl $animation wheel_rl_spin240 "digger_wheelspin" frame 6 6 subtract neutral 0 weightlist wheel_rl $sequence wheel_rl_spin { wheel_rl_spin0 wheel_rl_spin120 wheel_rl_spin240 wheel_rl_spin0 blendwidth 4 blend "vehicle_wheel_rl_spin" -180 180 } weightlist wheel_rl delta autoplay
運転者視点
もし乗り物が運転できるものなら、運転者の視点をあらわすAttachmentポイントの配置も必要です。
$attachment vehicle_driver_eyes "view" 0 0 0
vehicle_driver_eyes
という名前にする必要があります。
アニメーション早見表
これはアニメーションの必要がある部分の早見表です。以下が必要になります:
-サスペンション - 3フレーム - frame0: 車輪の一番低い位置; frame1: 車輪の通常位置; frame2: 車輪の一番高い位置 -ターン - 3フレーム - frame0: 左に曲がる; frame1: 中央; frame2: 右に曲がる -回転 - 9フレーム - frame0: 0度の車輪; frame9:前に360度回転した車輪
乗り物に備え付け武器があるなら(ここでは武器が1つだけとします):
-狙う(aim) - 9 フレーム - frame0: 武器は左下を狙う; frame1: 武器は中央下を狙う; frame2: 武器は右下を狙う; frame3: 武器は左を狙う; frame4: 武器は中央を狙う; frame5: 武器は右を狙う; frame6: 武器は左上を狙う; frame7: 武器は中央上を狙う; 武器は右上を狙う
これらが基本のプレイヤーが運転できる乗り物に必要なものです。追加のアニメーションはsourcesdk_content\hl2\modelsrc\Buggy
で見ることができます。
スクリプト
乗り物が正しく機能するにはスクリプトが必要です。ほぼ全ての乗り物の特性をスクリプトでコントロールすることができます。
スクリプトに変数の宣言がない場合、コードの中に埋め込まれた初期値を使います。変数を書くブロックを間違えると致命的なクラッシュを起こすことになります。 スクリプトは特性ごとに別のブロックにわかれています。
"vehicle" { "body" { "massCenterOverride" "0 0 0" "massoverride" "800" "addgravity" "0.33" } 以下設定が続く }
これは乗り物の車体の基礎を定義します。定義の中でかけている変数があれば初期値が使われます。これらの設定はSDK内のjeep_text.txtからコピーしたものです。
massCenterOverrideは乗り物のローカル原点(.MDLで定義)にあわせて重心を調整します。
Mass(質量)とGravity(重力)は明らかに違ったものです。
Mass(質量)は乗り物を重くし、Gravity(重力)は下向きの力を作ります。どちらも馬力と調整する必要があります。Mass(質量)は常に明らかですが、Gravity(重力)は坂を上がるときに一番明らかになります。平らな地面での運動にはGravity(重力)は影響しません。
乗り物は過剰決定体系のシステムです。密接に関係したパラメータが多く、パラメータの調整(特にランダムにする場合)が難しいときがあります。
"offset"は原点から車軸までの距離です。"wheeloffset"はその車軸から個々の車輪までの距離です。この値はそれぞれの車輪に対称にプラスマイナスをかけてコピーされます(1つの車軸に2つの車輪というものしかサポートしていません)。 注意:モデルに"wheel_fl"といった車輪attachmentがある場合、乗り物のコードが自動的に値を計算するのでスクリプトにいれる必要はありません。
keepuprighttorqueは他の何にも接続されていません。
tiltforceはコード内で決められた限界を超えて横転した乗り物に適用する重力の値です。
tiltforceheightはその追加の重力を適用する場所への距離です。 この2つのパラメータをあわせて乗り物が横転した時に質量中心が変わることのシミュレートを行おうとしています。
countertorqueは車輪のトルクがどのくらい車体に働くかのスケールを調整します。
Wheel mass(車輪質量)はサスペンションを通じて車体に影響を及ぼします。
massCenterOverrideは横転を防ぐのにとても役立ちます。車体は完全に剛体で、質量分布が一様であることに気をつけてください。これは実際の車と比べると貧弱なシミュレーションモデルです。実際の車の質量は底(サスペンション)に集中し、 車内は大部分が空洞なので質量があまりありません。それなので一般的に重心を車の衝突モデルの中心ではない場所に移したいとおもうでしょう。車が横転するのを防ぐhackが必要ならこの重心を地面の下まで移動させることもできます。