HUDをいじるには?



・HUD(´・ω・`)?
残り体力、シールド、弾薬数、武器選択スロット、「*どくね*」でお馴染み 金魚の糞どものストーキング状況・・・などなど、HL2のゲーム画面には HUDに色んな情報が表示されてます。
これらの表示もVGUIのコントロールクラスをペタペタ貼り付けて実現 しているんですよ。

で、興味を持ったアナタがHUDって何の略かと検索してみたら・・・やたらV6の映画タイトルがヒットします。

・どこに貼るの?
VGUIコントロールの新規追加例」では GAME UI DLLパネルを親にFrameクラスを使ってウインドウの表示を行う際、 GAME UI DLLパネルのハンドル(vgui::VPANEL)を取り出して利用しました。 GAME UI DLLパネルも含めた主要パネルのハンドルをゲットする方法を復習すると。

  • GAME UI DLLパネル→ enginevgui->GetPanel( PANEL_GAMEUIDLL )
  • CLIENT DLLパネル→ enginevgui->GetPanel( PANEL_CLIENTDLL )
  • TOOLS パネル→ enginevgui->GetPanel( PANEL_TOOLS )


  • HUDとして使用するパネル(各種VGUIコントロールを配置する親パネル)はCLIENT DLLパネル の子コントロールのビューポートパネルになります。

    「じゃあ、そのCLIENT DLLパネルから子コントロールを辿ってビューポートパネルにアクセスすりゃいいの?」

    といきたいところですが、出来ません。親から子を辿るにはCLIENT DLLパネルのハンドルではなく、 CLIENT DLLパネルのポインタが必要です。

    「そんじゃあCLIENT DLLパネルに子コントロール貼り付けてそのクラスからGetParent()を実行すりゃCLIENT DLLパネルのポインタが取れるんじゃない?」

    これもできまへん。

    こっちでは子コントロールから親のCLIENT DLLパネルハンドルは取れるようですが、
    VPANEL GetVParent()

    こっちだとNULLが返ってきちゃいます。
    Panel *GetVParent()

    要するに「主要パネルはお前らの勝手にはさせねえよ」ってことでしょう。


    結局ビューポートパネルにはどうアクセスすんだよっていうと

    g_pClientMode->GetViewport()

    コレですわ。

    ・ペタコンペタコン
    おっしゃ、好きなコントロールをビューポートパネルにペタコンペタコン 貼ってきゃいいんだな〜、なんて調子に乗って「hajimeteno VGUI」を ビューポートパネルに貼り付けたら。あらやだ、移動したり、撃ったりできないやん。


    Uzeeee!

    というわけでポップアップタイプのコントロールのように、それ自身がフォーカスを取得して マウスやキーボード操作の入力を受付けてしてしまうようなコントロールを貼り付けると非常に 邪魔臭いです。せいぜいチャットメッセージ入力時に使うぐらいですかね。

    通常、HUD部品パネルの新規宣言/定義〜実行時作成処理までの流れを大雑把に分けると以下のような形になります。

  • HUD部品用のベースクラスを継承してHUDの部品パネルクラスを宣言します、継承するクラスは CHudElementクラスとVGUIコントロールクラスを多重継承した形になります(CHudElementとPanelクラスの組み合わせが多いですね)。
  • DECLARE_HUDELEMENT、もしくはDECLARE_HUDELEMENT_DEPTH マクロの引数に新規追加のHUD部品クラスを指定しておく。DECLARE_HUDELEMENT_DEPTHの 第2引数に渡すdepthに大きい値を指定するほど、HUD部品を一斉に作成する際、先に作成されることになる(後から作られた部品よりも背面にまわされる)。
  • MODフォルダ下のscripts/HudLayout.resに自分の作成したHUDの部品パネルのレイアウト設定定義を追加。
  • HL2実行時、client.dllがロードされた際、

  • (1)HUDヘルパによってHUD部品クラスを作成する関数ポインタのリストが作成される。 (DECLARE_HUDELEMENT、またはDECLARE_HUDELEMENT_DEPTHマクロによって対象の関数は定義されちゃってます)。
    (2)HUDの初期化処理時、一斉にそのリスト上の関数が呼び出されてHUDの部品が作成される。
    (3)作成された部品に対してHudLayout.resの設定が適用される。


    さらに乱暴に分けると

  • YOUはCHudElementクラス+なんでもいいからポップアップしないVGUIのコントロールクラスを継承して新しくクラス宣言しちゃいなよ。
  • YOUはDECLARE_HUDELEMENTマクロの括弧ん中にそのクラス書いちゃいなよ。
  • YOUはscripts/HudLayout.resに部品パネルのレイアウト定義足しちゃいなよ。

  • こんだけなら、オラ、何だか出来そうな気がしてきたぞ。

    (´・ω・`)つもどる