prop_data
プロップデータ
プロップデータシステムの目的は、1つのゲーム・MODの全てのマップを通じて、プロップモデルのインタラクティブな振る舞いの一貫性を保証することです。 3つの中心となるプロップエンティティ(prop_static 、prop_dynamic 、prop_physics )全ては、モデルに埋め込まれたゲーム関連データをプロップデータシステムを使って読み込みます。この記事はモデルのプロップデータに埋め込まれたデータを説明し、その編集方法を示します。
コアデータファイル
プロップデータシステムはデータを階層的に保存します。基本となるプロップデータクラスはmod\scripts\propdata.txt
の中に記述されています。可能な限り、モデルは自身の特有のクラスを定義するのではなく、これらに用意されたクラスを使用すべきです。 こうすることで、プロップモデル全体に適用される変更をコンテントの再ビルドをまったく行わずに実行することができます。(例えば、HL2のプレイテストのフィードバックを受けて、全てのゲーム中木製オブジェクトに対する強度調整を何回か行いました。)
propdata.txt
の記述形式はKeyValue形式で、それぞれのエントリーは以下のようになっています:
"プロップデータクラス名" { "key" "value" ... }
キーとその適正な値(value)を以下に説明します:
- "base"
- <string>(文字列)
propdata.txt
ファイルで定義された他のプロップデータクラスの名前である必要があります。指定した場合、このプロップデータクラスはベースとなったクラスからの全てのデータを引き継ぎます。このクラスで更にキー指定を行うとベースクラスのキーを上書きします。
- "blockLOS"
- <integer>(整数) このプロップがNPCの視線(Line-Of-Sight)をブロックするかどうかの設定を上書きします。指定がない場合、プロップはNPCの視線を遮るかどうかを自身の大きさによって決定します。"0"や"1"に指定することでブロックするかどうか望みどおりに決めることができます。
- "AIWalkable"
- <integer>(整数) AIがこのプロップの上を歩くことができるか判断するのに使われます。"0"か"1"に設定できます。
- "health"
- <integer>(整数) どれだけダメージを受けたらプロップが壊れるかを指定します。指定がない場合、及び"0"に設定された場合は、プロップはダメージを受けず、壊れることがありません。
- "damage_table"
- <string>(文字列) このプロップで使用するカスタム物理ダメージテーブルを指定します。MODは自身のコードの中でダメージテーブルを定義する必要があります。HL2のカスタムダメージテーブルは1つだけで"glass"(ガラス)です。これは落としただけで壊れるような非常に壊れやすいオブジェクトに使用できます。
- "dmg.bullets"
- <float>(小数) このプロップの弾丸ダメージを調整します。初期値は"1.0"です。
- "dmg.club"
- <float>(小数) このプロップへの殴りダメージを調整します。初期値は"1.0"です。
- "dmg.explosive"
- <float>(小数) このプロップへの爆発ダメージを調整します。初期値は"1.0"です。
- これらのダメージ調整パラメータはオブジェクトが様々なダメージタイプからのダメージ量の違いを表現するために使ってください。全体としてのダメージへの強度を表現するためには使わないでください。例: 石は全てに対して強いものです。これを表現するには、石オブジェクトのhealth(強度)をあげてください。ここで全てのダメージ調整パラメータを下げることはしないでください。
- "explosive_damage"
- <float>(小数) このプロップが壊れたときの爆発ダメージ量
- "explosive_radius"
- <float>(小数) このプロップが壊れたときの爆発半径
- これら2つの項目が指定されていると、そのプロップは壊れたときに指定した大きさ、ダメージで爆発するようになります。
- "breakable_model"
- <string>(文字列) これはプロップが壊れたときのgeneric breakable gib(一般的な破片)セットを指定します。これはプロップにカスタム破片の設定がないときだけ必要です。ここで指定できる名前は
propdata.txt
のgeneric breakableセクションで定義されたものです。詳しくは下の壊れるモデル(Breakables)セクションを見てください。
- breakable_skin
- <integer>(整数) generic breakable gibモデルで使うスキンの指定
- "breakable_count"
- <integer>(整数) 何個のgeneric breakable gibに分かれるかの設定
- "allowstatic"
- <integer>(整数) プロップを上書きして、物理シミュレーションモデルとしてだけではなくstaticモデル(prop_static)としても使えるようにします。一般的に、これは使用しないでください。
追加して、以下のキーがマルチプレイヤー向けプロップにおいて使用されます:
- "physicsmode"
- <integer>(整数) このプロップが使用する物理モードを指定します。以下のどれかに設定してください:
- "1" : ソリッド(剛体)でプレイヤーを押しのける
- "2" : 非ソリッドだが、プレイヤーによって押しのけられる
- "3" : 非ソリッドで、クライアント側シミュレーションのみ
- "multiplayer_break"
- <string>(文字列) マルチプレイヤープロップが壊れる時の方法を選択します。以下のどれかに設定してください:
- "both" : サーバーとクライアント両方に破片(gib)を生成
- "server" : サーバだけで破片を生成
- "client" : クライアントだけで破片を生成。これがデフォルトです。
プロップモデルの設定
プロップとして使うモデルを作り上げたら、プロップデータの設定をする必要があります。プロップデータはモデルの.QC ファイルの$keyvaluesセクションに埋め込まれます。まず、プロップがどのようにシミュレーションされるべきか決定しましょう。HL2では以下の一般則に従うようにしました:
- 何かに接続したり、動かないもののサポートとなるのなら、static(静的)であるべきだ。
- 光を出すのなら、staticであるべきだ。
- とても大きく、プレイヤーがまったく動かせないのなら、staticであるべきだ。
- それ以外のものは、物理的にシミュレーションされるべきだ。
もしプロップをstaticにしたいのなら、もうここで作業は終わりです。$keyvaluesセクションにプロップデータセクションがないモデルは強制的にstaticになります。そうしたモデルをprop_physicsエンティティを使ってマップに配置すると、ゲーム内では取り除かれ、警告が表示されます。
もしプロップを物理的にシミュレーションしたいのなら、モデルの.QC ファイルに$keyvaluesセクションを追加する必要があります。もし自分の.qcに$keyvaluesセクションがないのなら、このコードのかたまりをそのまま追加してください。もしすてに$keyvaluesがあるのなら、その最後に"prop_data"セクションを追加してください。$keyvaluesの例は以下のようになります:
$keyvalues { "prop_data" { "base" "Wooden.Small" "dmg.bullets" "0" "explosive_damage" "100" "explosive_radius" "100" } }
この例となるプロップデータでは、まずpropdata.txt
の"Wooden.Small"から属性を引き継ぐことを指定しています。それからいくつかの変数を上書きして、弾丸ダメージへ無敵にし、壊れたときに爆発するようにしています。プロップで使用できる基本プロップクラスを見つけるには、mod/scripts/propdata.txt
ファイルを開き、自分のプロップに一番あったものを探してください。"<材質名>.<サイズ>"のものを選び、材質にあったダメージ調整パラメータだけを設定している"<材質名>.Base"を使わないように気をつけてください。
プロップを作成する場合、以下のTipに従うことでゲーム/MOD中での一貫性を保つことができます:
- プロップで強度(health)を上書きしないようにします。その代わりに、プロップクラスを選び、そのクラスの強度を使うようにします。こうすることで、他の椅子の2倍強度がある椅子というのがまぎれこまなくなります。
- 可能な限り、1つのプロップの中で材質種類を混ぜないようにします。つまり、半分金属、半分木製のプロップを作らないでください。
- 変える十分な理由がなければHL2のルールに従ってください:金属とプラスティックは壊れません。他のものは壊れます。
- 複数のオブジェクトをまとめて1つにするのは避けてください。とくに他の場所で同じようなオブジェクトを個別にシミュレーションする場合です。
- シミュレーションを行わない動く部分やマテリアルは避けてください。 つかり、コートラックにコートをかけないでください。
壊れるモデル(Breakables)
プロップデータシステムはまたgeneric breakable gibも扱います。このgeneric breakable gibはカスタムの破片(gib)をもたない壊れるオブジェクトにおいて使用されます。一般的には、カスタムの破片はgeneric breakable gibよりはるかに優れたものですが、どのくらいの数のカスタム破片をメモリにつめこめるかには限度があります。プロップのカスタム破片を作るにはCreating Custom Breakable Gibs を見てください。そうでない場合は読みすすめてください。
オブジェクトのプロップデータの"breakable_model"はモデルが使用するgeneric gibモデルを指定し、"breakable_count"がその数を指定します。ほとんどの壊れるプロップデータベースクラスは破片に使用するモデルを指定し、そこから派生し<材質名>.<サイズ>クラスがその量を指定しています。さらに"breakable_skin"で破片モデルのスキンを指定して、壊れる前のモデルのマテリアルに近づけることもできます。
Generic gibの種類はmod/scripts/propdata.txt
ファイルの最後に以下の形式で定義されています:
"BreakableModels" { "gib set name" { "gib model" "1" "gib model" "1" "gib model" "1" ... } "gib set name" ... }
"gib model"は使用するモデル(例えば"models\Gibs\wood_gib01e.mdl")を指定します。最小から最大の順に並べられています。プロップデータシステムは出来る限り、壊れるモデルのサイズ範囲の中にgeneric gibモデルを出そうとします。
物理インタラクション
プロップデータシステムはプロップの一貫性を保証するだけではなく、プロップの様々な物理インタラクションをオンにするためにも使われます。これらはプロップデータセクションにキーバリューセクションを埋め込むことで行います。HL2では重力銃 とのインタラクションと火とのインタラクションを使うことができます。 重力銃 とのインタラクション設定は以下の形式でプロップデータセクション内に定義されます:
"prop_data" { ... "physgun_interactions" { "key" "value" ... } }
キーとその適正な値(value)を以下に説明します:
- "onworldimpact" "stick"
- このプロップは重力銃から打ち出されるとworld (世界、マップ)に刺さって埋め込まれます。
- onfirstimpact"
- <string>(文字列) 重力銃から打ち出されて何かに最初にぶつかったときの振る舞い。以下のどれかを指定できます:
- "break"
- このプロップは発射されて最初に何かにぶつかったところで必ず壊れます。
- "break"
- "paintsplat"
- このプロップは発射されて最初に当たったものにデカルをペイントします。
- "paintsplat"
- "impale"
- このプロップは発射されて最初に当たったものを貫通します。HL2では未使用なので現状ではサポートされていません。
- "impale"
- "onlaunch"
- <string>(文字列) 重力銃で最初に発射された時のプロップの振る舞い。以下のどれかを指定できます:
- "spin_none"
- このプロップは重力銃から発射された時に回転しません。デフォルトでは、重力銃は発射するオブジェクトにランダムな回転速度を適用します。それを防ぐにはこのオプションを使ってください。
- "spin_none"
- "spin_zaxis"
- このプロップは重力銃から発射された時にZ軸で回転します。
- "spin_zaxis"
- "onbreak" "explode_fire"
- このプロップが壊れて爆発するときに近くの敵を発火させます。
- "damage" "none"
- このプロップはダメージに反応して動くことがありません。他のプロップデータの内容によってはダメージを受けることもありますが、ダメージの衝撃で動くことはありません。
火のインタラクションの設定は以下の形式でプロップデータセクション内に定義されます:
"prop_data" { ... "fire_interactions" { "key" "value" ... } }
キーとその適正な値(value)を以下に説明します:
- "ignite" "halfhealth"
- このプロップはhealth(強度、体力)が最初の半分になったときに自己発火します。
- "explosive_resist" "yes"
- これによって爆破ダメージを減少させる特別な振る舞いを設定します。このプロップが死ぬ(壊れる)ほどの爆発ダメージを受けそうなときに、ダメージを死なない程度に減少させ、その代わりに自身を発火させます。
- "flammable" "yes"
- このプロップは発火ダメージ(近くの火、"explode_fire"の重力銃インタラクションがマークされたプロップなど)を受けると発火します。HL2では未使用なので現状ではサポートされていません。
プロトタイピング
プロトタイプの作業をする場合や、モデラーが近くにいない場合、プロップデータシステムの強制を回避する方法が役に立ちます。このためには、prop_physics やprop_dynamic の代わりにprop_physics_override やprop_dynamic_override エンティティを使用してください。prop_physics_override はStaticのモデル(つまり.QCファイルの$keyvaluesに"prop_data"のデータが無いモデル)を割り当てても自身を取り除きません。またこのエンティティを使うことでマップデザイナーがプロップの"health"(強度、体力)を設定することができます。
overrideエンティティを使うことでプロトタイプ作業中や、モデラーが指定した属性を持った新しいモデルを完成させるまで、一時的に正しく設定されていないモデルを使うことができます。ハンマーのEntity Report の機能を使ってマップを公開するときにはoverrideエンティティが残っていないことを確かめることを強く推奨します。さもないと、物理の一貫性がないものをリリースすることになり、プレイヤーはとても早く気づくことになります(あのオレンジバケツはこのマップで撃ったときには動かなかったのに、別の前のマップでは動いた)。