unity

【Unity:2D】ダメージUIをポップアップで表示する【凄く簡単】

こんにちは、しろうです。

今回は『ダメージUIを敵キャラの頭上にポップアップで表示する』ということをやってみたいと思います。

これを応用すれば下記のようなダメージUIを作成することが可能です。(下記は僕が初めてリリースしたアプリですw)

かなり簡単なのでサクッと解説していきます。

手順としては下記の通りです。

手順①:テキストプレハブを作成

まずはこんな感じで、敵オブジェクトとテキストを用意します。

今回は「Enemy」と「DamageText」という名前にしました。

テキストプレハブには上記画像のように後からRigitbody2Dをアタッチしてください。(スクリプトは後から作ったものをアタッチしてください。)

手順②:スクリプトを生成

今回作成するスクリプトは「テキストプレハブに動きを加えるスクリプト(DamageTextController.cs)」「敵の位置にテキストプレハブを生成するスクリプト(AttackController.cs)」の2つです。

テキストプレハブに動きを加えるスクリプト(DamageTextController.cs)

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

public class DamageTextController : MonoBehaviour
{    

    void Start()
    {
        GetComponent<Rigidbody2D>().AddForce(new Vector3(0, 300, 0));
        StartCoroutine(DestroyObject());
    }

    // Update is called once per frame
    void Update()
    {
        StartCoroutine(DestroyObject());
    }

    private IEnumerator DestroyObject()
    {
        yield return new WaitForSeconds(0.6f);
        Destroy(this.gameObject);
    }
}

 

こちらのコードはテキストプレハブにアタッチするものです。(こちらの記事を参考にさせて頂きました。)

AddForceメソッドの引数を好きな値にして頂ければもう少しテキストの動きに変化を加えられます。

また、知らない人のためにUpdate関数より下を解説しておくと

StartCoroutine(DestroyObject());

こちらはコルーチン(途中で処理を中断できるまとまり)と呼ばれるもので、IEnumeratorとセットで使われます。

使い方は簡単でまずはいつも通り関数を作り、関数名の前にIEnumeratorと記述。
関数の中に「yield return new WaitForSeconds(0.6f);」を記述することで、引数に与えた秒数後にこのコードよりしたのコード(今回の場合は「Destroy(this.gameObject);」)が実行されます。

あとは作った関数をStartCoroutin()の引数に与えてやれば完成です。

コルーチンについて詳しく知りたい方は「Unity公式リファレンス」をどうぞ(*・ω・)ノ

 

敵の位置にテキストプレハブを生成するスクリプト(AttackController.cs)

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

public class AttackController : MonoBehaviour
{
    [SerializeField] private Text damageText; //ダーメージテキストを格納
    [SerializeField] private GameObject enemy; //敵キャラを格納

    private Vector3 enemyPos;//敵キャラの座標を格納
    private GameObject canvas;//親にするキャンバスを格納


    // Start is called before the first frame update
    void Start()
    {
        //敵キャラの座標を取得
        enemyPos = enemy.GetComponent<Transform>().position;

        //親にするキャンバスを取得
        canvas = GameObject.Find("Canvas");
    }

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

    public void Attack()
    {
        Text text;
        text = Instantiate(damageText, new Vector3(0,0,0), Quaternion.identity);
        text.transform.SetParent(canvas.transform, false);
        text.transform.position = enemyPos;
    }
}

 

こちらはCanvasにアタッチするコードです。

今回はテスト用なので「スペースキーを押したら、敵キャラの座標にテキストが表示され」る」という処理にしました。

ポイントとしては text.transform.SetParent(canvas.transform, false); この一文でしょうか。

テキストプレハブはUIなので、必ずCanvasの子にする必要があります。そのためSetParentメソッドを使います。第一引数に親にするオブジェクト、第二引数はfalseにすることでローカル座標系を維持して、指定したオブジェクトの子として生成できます。(第二引数を与えないとワールド座標系になってしまって、変なことになるので注意。)

あとは最後のコードでテキストを敵座標に生成しています。

「敵キャラが複数いる場合」や「シーンに最初から存在していない場合」などの時は敵キャラの参照方法を少し変更すれば上手くいくはずです。(例えば「OnColliderとかを使って当たった敵の座標を取得して、その値をtextに与える」とか)

手順③:スクリプトをアタッチ、Canvasの設定

あとはAttackControllerスクリプトを「Canvas」(インスペクター上で「DamageTextオブジェクト」と「Enemyオブジェクト」を付けることを忘れず。)とDamageTextスクリプトを「DamageTextプレハブ」にそれぞれアタッチしましょう。

それとCanvasの設定を少し変える必要があります。

画像のように「RenderMode」を[ScreenSpace-Camera]にして「MainCamera」を[RenderCamera]にアタッチ。

はい、これで作業は終了。

下記のようになったら成功です。

 

 

何か困ったことや相談事がありましたらTwitter(shiro_life0)よりお気軽にご相談ください!

それではまたっ!