第七章(´・ω・`)おばあちゃん、アクティビティ・リストと武器ビューモデルのアニメーションについて考えるわよ☆



・どうして?

前章で作成したマグナムのクローン武器「ゲロ銃」、モデルにガッポイライフル(AR2)を 使ってるのにコンソールから
sv_cheats 1
impulse 101

を実行した後でリロードしてみるとリロードのアニメーションがちゃんと動いてます。
本来使用すべき物とは別の武器モデルなのに異常は発生したりしないのか?目線飛びまくりの台詞棒読み子役並にイライラするぜ。

・アクティビティ・リスト

ai_activity.hというヘッダファイルの 中身を見るとACT_〜で始まる名前のenumの列挙型定数定義が延々と続いています(-1,0,1,2,3.....)。
typedef enum
{
	ACT_INVALID = -1,
	ACT_RESET = 0,
	ACT_IDLE,
	ACT_TRANSITION,
	ACT_COVER,
	ACT_COVER_MED,
	ACT_COVER_LOW,
	ACT_WALK,
	ACT_WALK_AIM,
		・
		・
		・


また、activitylist.cppの184行目からは そのenum定義を引数にREGISTER_SHARED_ACTIVITYマクロのオンパレードです。
void ActivityList_RegisterSharedActivities( void )
{
	REGISTER_SHARED_ACTIVITY( ACT_RESET );
	REGISTER_SHARED_ACTIVITY( ACT_IDLE );
	REGISTER_SHARED_ACTIVITY( ACT_TRANSITION );
	REGISTER_SHARED_ACTIVITY( ACT_COVER );
	REGISTER_SHARED_ACTIVITY( ACT_COVER_MED );
	REGISTER_SHARED_ACTIVITY( ACT_COVER_LOW );
		・
		・
		・


何やってんでしょうね?
これはREGISTER_SHARED_ACTIVITYマクロを使って アクティビティの名称とenum定義の定数を「アクティビティ・リスト」に登録しているのです。
例えば
	REGISTER_SHARED_ACTIVITY( ACT_TRANSITION );
の場合"ACT_TRANSITION"という文字列と、ACT_TRANSITIONに定義された定数 2 が対に なってアクティビティ・リストへ登録されます。


( ゚Д゚)y-~ 早い話、"ACT_TRANSITION"って文字列から 2 って数字が見つかるし、 その逆もできる仕組みが存在するということだけ知ってれば上のダラダラした説明は3分後に忘れてもOK。目線飛びまくりの台詞棒読み子役並にどうでもいいんです。

・武器ビューモデルのアニメ再生
前章のゲロ銃作成の元に使ったマグナムのソースweapon_357.cppの119行目に
	SendWeaponAnim( ACT_VM_PRIMARYATTACK );
という記述があります。これは発砲の処理時にプレイヤーのビューモデルが「バーン!」の動きを するように指定してるんです。

南海キャンディーズでーす、バーン!

しかし、ACT_VM_PRIMARYATTACKには 163 という定数が定義 されてるのですが、なんでこれを指定してモデルがバーン!の動きを再生できるのか?
武器ビューモデルのMDLファイルv_357.mdl側に「163ならバーンしる!」なんて拡張性もへったくれ もない情報があるとは考え難いのです。

そこで実際に確認
  • GCFScapeでsource models.gcfをひらいて〜♪
  • /root/hl2/models/Weapons/v_357.mdlを取り出して〜♪
  • v_357.mdlをバイナリエディタでひらいて〜♪
  • OMG!!"ACT_VM_PRIMARYATTACK"という文字列を見つけたワァー(n‘∀‘)η♪


  • ・・・なんてことはしなくてもいいんですよ奥様

    替わりにSourceSDKのインストール先から更にゴリゴリーっと掘り下げた・・・

    C:\Program Files\Valve\Steam\SteamApps\××××\sourcesdk_content\hl2\modelsrc\weapons\v_357

    上記の階層にある
    v_357.qcというファイルをひらきます。モデリングに関しては幼稚園児並みの知識しかないおばあちゃんでも、 これが懐かしのQuakeCファイルではなく、モデルのコンパイルに関係しているファイルであることは分かります。
    v_357.qcの一部
    $sequence idle01 "Idle01" loop fps 30 activity ACT_VM_IDLE 1 node Ready
    $sequence fire "Fire01" snap fps 30 activity ACT_VM_PRIMARYATTACK 1
    { event AE_MUZZLEFLASH 0 "357 muzzle" } node Fire
    $sequence draw "Draw" snap fps 30 activity ACT_VM_DRAW 1 node Ready
    $sequence reload "Reload" fps 30 activity ACT_VM_RELOAD 1 node Ready {
    { event AE_CL_PLAYSOUND 28 "Weapon_357.OpenLoader" }
    { event AE_CL_PLAYSOUND 39 "Weapon_357.RemoveLoader" }
    { event 3015 55 } 
    { event AE_CL_PLAYSOUND 67 "Weapon_357.ReplaceLoader" }
    { event AE_CL_PLAYSOUND 92 "Weapon_357.Spin" }
    }
    
    $sequence holster "Holster" fps 30 activity ACT_VM_HOLSTER 1 node Ready
    $sequence idletolow "idle_to_low" fps 30 activity ACT_VM_LOWERED_TO_IDLE 1  transition Ready Low 
    $sequence lowtoidle "low_to_idle" fps 30 activity ACT_VM_IDLE_TO_LOWERED 1 transition Low Ready
    $sequence lowidle "Low_idle" fps 30 loop activity ACT_VM_IDLE_LOWERED 1 node Low
    
    赤い部分を見てください。全部ai_activity.hヘッダファイル上で見つかる名称ですね。
    そしてセクシャルバイオレットの部分はSourceSDKのモデルビューアで表示されるシーケンスの名称です。


    これで分かりましたね、MDLファイルにはアクティビティの名称が文字列データで組込まれているのです、武器ビューモデルの発砲アニメーション再生までの流れをかなり乱暴に説明するとこんな感じです。
    (´・ω・`) アニメーション再生係 なんか再生したいモーション、ある?
    ミ.,,゚Д゚彡 weapon_357武器クラス プライマリ武器の発砲モーションACT_VM_PRIMARYATTACK再生してくれや
    (´・ω・`) アニメーション再生係 あい、ACT_VM_PRIMARYATTACKに対応している文字列表現はなんでつか?
    ( ゚Д゚) アクティビティ・リスト "ACT_VM_PRIMARYATTACK"だよ
    (´・ω・`) アニメーション再生係 "ACT_VM_PRIMARYATTACK"に該当する再生ポインタをください
    (n‘∀‘)η ビューモデルv_357.mdlキャッシュデータ "ACT_VM_PRIMARYATTACK"再生ポインタどぞー!
    (´・ω・`) アニメーション再生係 イエス!再生ポインタゲッツ&再生!
    ミ.,,゚Д゚彡 weapon_357武器クラス さんくすアイラブユー

    ・ゲロ銃の疑問解決
    前章で作成したゲロ銃、あれはマグナムweapon_357クラスのクローンなので、当然weapon_357と同じ以下のアクティビティを使用していることになります。
    ACT_VM_IDLE アイドル状態
    ACT_VM_PRIMARYATTACK プライマリ武器発砲
    ACT_VM_DRAW 銃を取り出す
    ACT_VM_RELOAD リロード
    ACT_VM_HOLSTER 銃をしまう
    ACT_VM_LOWERED_TO_IDLE 銃をダラーンと下げた状態からアイドル状態に遷移
    ACT_VM_IDLE_TO_LOWERED アイドル状態から銃をダラーンと下げた状態に遷移
    ACT_VM_IDLE_LOWERED 銃をダラーンと下げた状態

    しかし、ゲロ銃ではビューモデルにv_357.mdlを使用せずにガッポイライフル(AR2)のモデルv_irifle.mdl を使用していました。でも動作に支障はありませんでしたよね?

    さっきと同じようにSourceSDKのインストール先から更にゴリゴリーっと掘り下げた・・・

    C:\Program Files\Valve\Steam\SteamApps\××××\sourcesdk_content\hl2\modelsrc\weapons\v_irifle

    上記の階層にある
    V_IRifle.qcというファイルを今度はひらいてみます。
    V_IRifle.qcの一部
    $sequence IR_idle "Idle" loop fps 30 activity ACT_VM_IDLE 1 node Ready
    $sequence IR_fire "Fire01" fps 30 snap activity ACT_VM_PRIMARYATTACK 1 
    { event AE_MUZZLEFLASH 0 "COMBINE MUZZLE" } node Fire
    $sequence fire2 "Fire02" snap fps 30 activity ACT_VM_RECOIL1 1 
    { event AE_MUZZLEFLASH 0 "COMBINE MUZZLE" } node Fire
    $sequence fire3 "Fire03" snap fps 30 activity ACT_VM_RECOIL2 1 
    { event AE_MUZZLEFLASH 0 "COMBINE MUZZLE" } node Fire
    $sequence fire4 "Fire04" snap fps 30 activity ACT_VM_RECOIL3 1 
    { event AE_MUZZLEFLASH 0 "COMBINE MUZZLE" } node Fire
    $sequence IR_fire2 "Alt_fire" fps 30 snap activity ACT_VM_SECONDARYATTACK 1 
    { event AE_MUZZLEFLASH 0 "COMBINE MUZZLE" }
    
    $sequence IR_reload "Reload" fps 30 activity ACT_VM_RELOAD 1 node Ready {
    { event AE_CL_PLAYSOUND 1 "Weapon_AR2.Reload_Rotate" }
    { event AE_CL_PLAYSOUND 19 "Weapon_AR2.Reload_Push" }
    }
    
    $sequence IR_draw "Draw" fps 30 snap activity ACT_VM_DRAW 1 node Ready
    $sequence IR_holster "Holster" fps 30 activity ACT_VM_HOLSTER 1 node Ready
    $sequence idletolow "idle_to_low" fps 30 activity ACT_VM_LOWERED_TO_IDLE 1  transition Ready Low
    $sequence lowtoidle "Low_to_idle" fps 30 activity ACT_VM_IDLE_TO_LOWERED 1 transition Low Ready
    $sequence lowidle "Low_idle" fps 30 loop activity ACT_VM_IDLE_LOWERED 1 node Low
    $sequence shake "Shake" fps 30 loop activity ACT_VM_FIDGET 1 node Fire
    

    理由は分かりましたね。ガッポイライフルはマグナムで必要な8つのアクティビティを全て持っているんです。

    アクティビティの名前が分かれば(バイナリエディタでMDLの末尾を見れば分かります)CSソースのモデルだって躊躇なくこのとおり。

    ( ゚∀゚)まったく、この世は地獄だぜ、アヒャヒャヒャヒャ!!

    ・おまけコーナー
    おまけとしてバグバイト君のビューモデルをガッポイライフル(AR2)の武器クラスで無理やり 使った例を載せときます。

    両者のQCファイル
    C:\Program Files\Valve\Steam\SteamApps\××××\sourcesdk_content\hl2\modelsrc\weapons\v_irifle\V_IRifle.qc


    C:\Program Files\Valve\Steam\SteamApps\××××\sourcesdk_content\hl2\modelsrc\weapons\v_bugbait\Bugbait.qc

    を比較すると、明らかにガッポイライフルで必要とされるアクティビティがバグバイトのビューモデルには存在しません。この場合、 該当するアクション発生時でもバグバイト君はボケーっとアイドル状態のままで、見てるこっちは(´・ω・`)ショボーンな結果になってしまいます。

    これを完全に解決するには

  • 不足分のアクティビティに割り当てる新たなシーケンスデータをSOFTIMAGEかなんかでポコポコ作る♪
  • そのシーケンスデータをSMDファイルへ吐く♪
  • QCファイルへシーケンスとアクティビティの組み合わせを追記♪
  • STUDIOMDLで再コンパイル♪



  • ・・・(´・ω・`)Nooo!おばあちゃんはSourceMODコーディングのお勉強に手いっぱいでSOFTIMAGEのお勉強してる時間ないわよ☆
    なので、現状バグバイト君が持っているシーケンスデータを使ってそれらし〜く動くようなビューモデル作りにチャレンジします。

    まず、オリジナルのバグバイト君のモデルデータが入っている
    C:\Program Files\Valve\Steam\SteamApps\××××\sourcesdk_content\hl2\modelsrc\weapons\v_bugbait
    上記のフォルダを丸ごとコピーして以下のフォルダを作成します(フォルダ名の後ろにXを足しただけ)
    C:\Program Files\Valve\Steam\SteamApps\××××\sourcesdk_content\hl2\modelsrc\weapons\v_bugbaitx



    そしてそのフォルダ下に以下の内容を持つQCファイルBugbaitx.qcを作成します。
    当然作るのは面倒なのでここからどぞ〜。つBugbaitx.qc
    Bugbaitx.qc
    # BUG BAIT X
    
    $modelname weapons/V_bugbaitx.mdl
    $cdmaterials models\Weapons\V_hand models\Weapons\V_bugbait
    
    // whole body
    $body studio "Bugbait_reference.smd"
    
    $origin 2 -4 67
    
    $attachment "muzzle" "ValveBiped.Bip01_R_Hand" 4 -4 0 rotate -90
    
    $sequence idle01 "Idle01" loop fps 30 activity ACT_VM_IDLE 1 node Ready
    $sequence fire "Squeeze" fps 30 activity ACT_VM_PRIMARYATTACK 1 {
     event AE_MUZZLEFLASH 0 "RPG MUZZLE"
    } node Fire
    $sequence fire2 "Squeeze" fps 30 activity ACT_VM_RECOIL1 1 {
     event AE_MUZZLEFLASH 0 "RPG MUZZLE"
    } node Fire
    $sequence fire3 "Squeeze" fps 30 activity ACT_VM_RECOIL2 1 {
     event AE_MUZZLEFLASH 0 "RPG MUZZLE"
    } node Fire
    $sequence fire4 "Squeeze" fps 30 activity ACT_VM_RECOIL3 1 {
     event AE_MUZZLEFLASH 0 "RPG MUZZLE"
    } node Fire
    $sequence sfire "Throw" frames 5 20 activity ACT_VM_SECONDARYATTACK 1 {
     event AE_MUZZLEFLASH 0 "RPG MUZZLE"
    } node Fire
    $sequence draw "Draw" snap fps 30 activity ACT_VM_DRAW 1 node Ready
    $sequence reload "Draw" fps 30 activity ACT_VM_RELOAD 1 node Ready {
    { event AE_CL_PLAYSOUND 20 "Weapon_Bugbait.Splat" }
    { event AE_CL_PLAYSOUND 30 "Weapon_Bugbait.Splat" }
    }
    
    $sequence holster "Holster" fps 30 activity ACT_VM_HOLSTER 1 node Ready
    $sequence idletolow "Idle01" fps 30 activity ACT_VM_LOWERED_TO_IDLE 1  transition Ready Low 
    $sequence lowtoidle "Idle01" fps 30 activity ACT_VM_IDLE_TO_LOWERED 1 transition Low Ready
    $sequence lowidle "Idle01" fps 30 loop activity ACT_VM_IDLE_LOWERED 1 node Low
    $sequence shake "Throw" loop frames 0 1 activity ACT_VM_FIDGET 1 node Fire
    

    赤いとこはアクティビティ名称、セクシャルバイオレットは SourceSDKのモデルビューアで表示されるシーケンスの名称、そしてウンコ色のとこが SMDファイル名(拡張子なし)。QCと同じフォルダの中に入ってますよね、但しBugbait_reference.smdは別物のファイルのようなので注意してください。

    ちなみにこの名前のアクティビティはソースコード中ではこんなアクションに使われてますんで(weapon_ar2.cpp参照)
    ACT_VM_RECOIL1 プライマリ武器連続発砲2発目
    ACT_VM_RECOIL2 プライマリ武器連続発砲3発目
    ACT_VM_RECOIL3 プライマリ武器連続発砲4発目以降
    ACT_VM_SECONDARYATTACK セカンダリ武器発砲
    ACT_VM_FIDGET セカンダリ武器発砲前の溜め


    次はSTUDIOMDLのEXEファイル
    C:\Program Files\Valve\Steam\SteamApps\××××\sourcesdk\bin\studiomdl.exe
    こいつのショートカットを作成し、面倒なのでBugbaitx.qcと同じとこへ持って持ってきちゃいます。


    SourceSDKの起動メニューダイアログで、現在選択されているゲームが自分のMOD(おばあちゃんのMODはボディコン☆)であることを確認したら Bugbaitx.qcをSTUDIOMDLのショートカットへドラッグ&ドロップ。

    (´・ω・`)確認!


    (´・ω・`)ドラッグ&ドロップ!

    DOS窓でなにやら実行されて成功すると
    C:\Program Files\Valve\Steam\SteamApps\SourceMods\Bodycon\models\weapons
    上記フォルダの下にはこ〜んなファイルができてるのれす〜♪
    V_bugbaitx.dx80.vtx
    V_bugbaitx.dx90.vtx
    v_bugbaitx.mdl
    V_bugbaitx.sw.vtx
    v_bugbaitx.vvd

    早速、第6章と同じ様に今度はガッポイライフルのスクリプトファイル
    C:\Program Files\Valve\Steam\SteamApps\SourceMods\Bodycon\scripts\weapon_ar2.txt
    こいつを開き、7行目のビューモデル指定を下の赤い部分のように書き換えちゃってください。
    Bugbaitx.qcの一部
    // Assault Rifle 2
    
    WeaponData
    {
    	// Weapon data is loaded by both the Game and Client DLLs.
    	"printname"	"#HL2_Pulse_Rifle"
    	"viewmodel"	"models/weapons/v_bugbaitx.mdl"
    	"playermodel"	"models/weapons/w_irifle.mdl"
    	"anim_prefix"	"ar2"
    


    おつかれさま〜、やっとゲーム起動です。

    ( ゚∀゚)よーし、お父さんモミモミしながら撃ちまくっちゃうぞ!アヒャヒャヒャヒャ!!

    QCファイルを色々いじくりながら再コンパイルして挙動を確かめてみましょう、 詳しい情報はモデリング関連の情報を扱っているサイトへ行って自分で調べてくらはい。
    おばあちゃんはモデリング関連、全くのド素人です。

    (´・ω・`)つ次へ