Unity: 敵の頭上に HP バーを表示する

Unity入門 - Project Bonfire

前回敵にダメージを与えることができるようになったので、ありきたりではありますが、今回は敵の頭上にHPバーを表示したいと思います。

Image の fillAmount を使って、こんな感じにHPバーの右端が斜めになるようにしてみました。

実装

スプライトの設定

UIを実装する前に、UIで使用する画像を読みこんで スプライトにしておきます。

Assets > UI の下にHPBar というフォルダを作成し、添付したファイルをドラッグアンドドロップで配置します。

それぞれ、Inspector で Textute Type を Sprite (2D and UI) に設定します。忘れずに Apply を押してください。

4つとも設定したら以下のようになります。

UI作成

UIの作成に入ります。

Hierarchy ビューで 右クリックし、Create Empty で空のGameObject を作成し、HPBar という名称にします。HPBar を作ったら、Inspector の Transform で Reset を実行します。

HPBar の下にUI の Image を作成します。

Canvas の下に Image が作成されます。作成された Image を BackgroundImage という名称に変えます。BackgroundImage の下にもう2つ Image を作成し、それぞれ ForegroundImage、BorderImage という名称にします。ForegroundImageは、スクリプトから呼び出すときに名称を使用するので、誤字に注意してください。

以下の画像がひととおり設定したところです。

Hierarchy で Canvas を選択し、Inspector で Render Mode を World Space に設定します。これによってゲーム内の世界にUIを表示できるようになります。

ここで1度 Canvas の Rect Transform を Reset しておきます。

リセットしたら、以下のように値を変更します。HPバーのサイズを変更する際は、この辺りを変更します。Width, Height, Scale などは好きなように調整してみてください。

続いて BackgroundImage を次のように設定します。

Source Image は、bar_white の代わりに bar_black を使っても構いません。Color のところは以下の画像の設定にしましたが、透明の加減のAlpha 値をお好みで変更してください。

今回の設定の中心となる ForegroundImage の設定です。

  • Anchor の位置が他と設定が異なるので注意してください。
  • Width と Height は Canvas と合わせます。
  • ImageType を Filled にします。
  • Fill Method を Horizontal にすることで水平方向に画像が消えるようになります。
  • Fill Origin を Right にすることで、画像の右側が残るようになります。このままでは左が短くなっていくので、短くなっていく分をスクリプトを使って画像を左にずらしていきます。これによって、右が減っているように見せます。

BorderImage の設定は次のようにしておきます。

スクリプトの取り付け

HPBar に HPbar.cs スクリプトを取り付けます。

プレハブ化

ここまでできたら、以下の画像のようにして、HPBar をプレハブ化します。

プレハブ化したら Inspector から HPBar を削除します。

敵キャラへの取り付け

敵キャラの paladin の 直下にHPBar を取り付けます。

Y の値を 2.2 くらいにすると頭上に配置されると思います。

実行するとこんな感じになり、攻撃するとHPが減っていくことが確認できると思います。

スクリプトの説明

簡単に説明します。

Start() 内で、HPを管理してる PlayerStatus を取得しておきます。また、値を操作する ForegroundImage も探しておきます。見ての通りですが、GetComponentsInChildrenですべての子のコンポーネントから “ForegroundImage”という名称のコンポーネントを取得します。

    public class HPBar : MonoBehaviour
    {
        RectTransform foreground = null;
        PlayerStatus status = null;

        void Start()
        {
            // 親 に付いている PlayerStatus を取得する
            status = transform.parent.GetComponent<PlayerStatus>();

            // ForegroundImage を探す
            foreach (RectTransform child in GetComponentsInChildren<RectTransform>() )
            {
                if (child.name == "ForegroundImage")
                {
                    foreground = child;
                }
            }

        }

        void Update()
        {
            float hpPercentage = (float)status.HP / (float)status.MaxHP;

            // ForegroundImage の画像をfillAmountで左から削り、localPositionで左に寄せる
            Image fg = foreground.GetComponent<Image>();
            fg.fillAmount = hpPercentage;
            foreground.localPosition = new Vector3(-100 + 100 * hpPercentage, 0, 0);

            // 常にカメラの方を向ける
            transform.forward = Camera.main.transform.forward;
        }
    }

Update() 内でやっていることは、大きく分けて2つです。HPバーの長さの調整と、HPバーをカメラ方向に向ける処理です。

まず HP / MaxHP で現在の HP の比率を出します。次に ForegroundImage の画像を fillAmount を利用してい比率の分だけ表示するようにします。このままだと左が減ってくるので、減った分だけ localPosision を操作して左に寄せます。これで右が減ったように見えます。

表示方向の調整ですが、HPバーが正面を向いていないと見づらいので、この処理を追加します。

スクリプトを直接編集して hpPercentage = 0.04 とかにすると、どこかで見たようなこんな表示になります。

左上に向かって消えていくのって、どうやって作れば良いんだろうと思っていたのですが、勝手にできていました。

おまけ:ソードアートオンライン風のHPバー

ここまでできたならば、…… ということで、ソードアートオンライン風のHPバーも作ってみました。

これだ!っていう作り方にたどり着いていないので概要だけ。今回やったのは、「Blender でメッシュを作成する」「テクスチャを貼る」「Shader で調整する」です。

とにかく視認性が最悪でした。かっこよく見えるのは以下の2つの画像の角度くらいで、あとは少しでもずれると見づらいです。なんとか使い物にならないかと思って調整を試みたのですが、Shader を思い通りに制御できず、途中で心折れました。機会があれば、もう1度挑戦してみるかも。

せっかくなので、上の2つの画像で下についている普通の HP バーは、常にこちらを向いていて見やすいというところを確認してください。

ファイル

おわりに

一応、敵の頭上にHPのバーが出せるようになりました。バーの右側を斜めにしていますが、画像なので好きな形にできます。

次回は武器の持ち替えを作りたいと思います。