【Unity】ダメージ表示を作ってみる【2D & 3D】

Unityのダメージ表示
スポンサーリンク

Unityのゲームで、敵にダメージを与えた時に頭上にダメージの数値を表示するUIを作ってみたいと思います。

ダメージを表示することで、結構ゲームらしくなるのでぜひ試してみてください!

こんな人におすすめ

・2Dゲームでダメージ表示を行いたい
・3Dゲームでダメージ表示を行いたい

2Dゲームでのダメージ表示UI

まずは2Dゲームでのダメージを表示するUIを作ってみたいと思います。

ダメージ表示に使うテキストを一つ作りましょう!(※ヒエラルキー上で右クリック→UI→Textで作れます。)

テキストの準備

桁数がわからないので、横幅は画面サイズに合わせて広めにとっています。名前はわかりやすくDamage Textに変更しました。また、UIボタンとの重なりがある場合を考えて、Raycast Target(画面タッチ時の当たり判定)はOFFにしています。

準備できたら、テキストに以下のスクリプトをアタッチします。

■DamageUI2D

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DamageUI2D : MonoBehaviour
{
    [SerializeField]
    private float DeleteTime = 1.5f;
    [SerializeField]
    private float MoveRange = 50.0f;
    [SerializeField]
    private float EndAlpha = 0.2f;

    private float TimeCnt;
    private Text NowText;

    void Start()
    {
        TimeCnt = 0.0f;
        Destroy(this.gameObject, DeleteTime);
        NowText = this.gameObject.GetComponent<Text>();
    }

    void Update()
    {
        TimeCnt += Time.deltaTime;
        this.gameObject.transform.localPosition += new Vector3(0,MoveRange / DeleteTime * Time.deltaTime,0);
        float _alpha = 1.0f - (1.0f - EndAlpha) * (TimeCnt / DeleteTime);
        if (_alpha <= 0.0f) _alpha = 0.0f;
        NowText.color = new Color(NowText.color.r, NowText.color.g, NowText.color.b, _alpha);
    }
}

スクリプトをアタッチしたら、次はアタッチしたオブジェクトをプレハブにします。なお、プレハブにする前に消えるまでの時間などは設定しておきましょう。

時間設定

・Delete Time
 消えるまでの時間
・Move Range
 消えるまでの時間にどれだけ上に上がるか
・End Alpha
 消える時の透明度(0〜1.0)

また、テキストの数字に縁取りを行いたい場合は、テキストのコンポーネント追加で「Outline」を追加しておきます。この辺りは、どういった表示を行いたいかで調整しましょう!

コンポーネントの追加

ちなみにプレハブにするときは、オブジェクトをアセット部分にドラッグアンドドロップするだけです。

プレハブ化

プレハブ化が完了したら、Canvasになるテキストは消してしまいましょう。以下のようにヒエラルキー上がなっていればOKです。

削除後

ここまで完了したら、次はダメージ表示を呼び出すためのサンプルスクリプトを作ります。以下のスクリプトをスプライトなどにアタッチしてください。なおスプライトは表示を確認するために、何か適当な画像を表示することをおすすめします。

■DamageTest

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DamageTest : MonoBehaviour
{
    [SerializeField]
    private GameObject ParentObj;
    [SerializeField]
    private GameObject DamageObj;
    [SerializeField]
    private GameObject PosObj;
    [SerializeField]
    private Vector3 AdjPos;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            ViewDamage(100);
        }
    }

    private void ViewDamage(int _damage)
    {
        GameObject _damageObj = Instantiate(DamageObj, ParentObj.transform);
        _damageObj.GetComponent<Text>().text = _damage.ToString();
        _damageObj.transform.position = RectTransformUtility.WorldToScreenPoint(Camera.main, PosObj.transform.position + AdjPos);
    }

}

あとは実際に実行状態で動きを確認してみましょう! スペースキーを押すと、スプライトの上に100が表示されると思います。実際に使用する場合は、当たり判定などでスペースキーを押した際の処理を呼び出します。

以上が2Dでのダメージ表示でした!

3Dゲームでのダメージ表示UI

3Dゲームでも基本的にやることは似ています。しかし、テキストではなくテキストメッシュを使うなど細かな部分が変わってきますので、準備を行っていきましょう。

空のゲームオブジェクトを作り、そこにテキストメッシュをコンポーネントとして追加します。

・ヒエラルキーで右クリック→「Create Empty」

空のオブジェクトの追加

・インスペクターで「Add Component」→「Text Mesh」

コンポーネントの追加

「Text Mesh」は、追加直後は文字がぼやけて表示されます。試しに文字を入力してみましょう。

テキストの参考

しっかりと表示がされるように以下のパラメーターを変更しましょう。また、文字配置も中央に変更しておきます。

・Character Size:0.1
・Anchor:Middle center
・Font Size:70

数値の変更

あとは以下のスクリプトを作ったゲームオブジェクトにアタッチします。

■DamageUI3D

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DamageUI3D : MonoBehaviour
{
    [SerializeField]
    private float DeleteTime = 1.0f;
    [SerializeField]
    private float MoveRange = 1.0f;
    [SerializeField]
    private float EndAlpha = 0;

    private float TimeCnt;
    private TextMesh NowText;

    // Start is called before the first frame update
    void Start()
    {
        TimeCnt = 0.0f;
        Destroy(this.gameObject, DeleteTime);
        NowText = this.gameObject.GetComponent<TextMesh>();
    }

    // Update is called once per frame
    void Update()
    {
        this.transform.LookAt(Camera.main.transform);
        TimeCnt += Time.deltaTime;
        this.gameObject.transform.localPosition += new Vector3(0, MoveRange / DeleteTime * Time.deltaTime, 0);
        this.gameObject.transform.Rotate(0, -180.0f, 0);
        float _alpha = 1.0f - (1.0f - EndAlpha) * (TimeCnt / DeleteTime);
        if (_alpha <= 0.0f) _alpha = 0.0f;
        NowText.color = new Color(NowText.color.r, NowText.color.g, NowText.color.b, _alpha);
    }
}

アタッチまで完了したら、消えるまでの時間等を設定し、2Dの場合と同じようにプレハブ化します。

時間設定

・Delete Time
 消えるまでの時間
・Move Range
 消えるまでの時間にどれだけ上に上がるか
・End Alpha
 消える時の透明度(0〜1.0)

※3D版のMove Ranegeは1など少ない数値にしておくことをおすすめします。

プレハブ化

ゲームオブジェクトの名前はわかりやすいように変更しました。

プレハブ化まで完了したら、ヒエラルキーにあるDamageTextオブジェクトは消してしまってOKです。

ここまで完了したら、次は実際に表示テストを行うために、Cube等のオブジェクトに以下のスクリプトをアタッチしてください。

■DamageTest

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DamageTest : MonoBehaviour
{
    [SerializeField]
    private GameObject DamageObj;
    [SerializeField]
    private GameObject PosObj;
    [SerializeField]
    private Vector3 AdjPos;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            ViewDamage(100);
        }
    }

    private void ViewDamage(int _damage)
    {
        GameObject _damageObj = Instantiate(DamageObj);
        _damageObj.GetComponent<TextMesh>().text = _damage.ToString();
        _damageObj.transform.position = PosObj.transform.position + AdjPos;
    }

}

アタッチ後のサンプル

アタッチ完了後はオブジェクトの設定を行います。設定まで完了したら、実際に実行状態にして動きを確認してみましょう!

スペースキーを押すとダメージが表示されます。

まとめ

以上が2Dと3Dにおけるダメージ表示UIについてでした! 簡単に実装できると思いますので、ぜひ試してみてください。