Help us understand the problem. What is going on with this article?

【unity】入手したアイテムのログを流すUIを作ってみた

どうも、N高等学校の生徒のシュンです。Unityが本当の意味でチョットデキルだけのよくある名前の人です。

この記事は、N高等学校アドベントカレンダー6日目の記事です。枠が空いているということで書くことにしました。
僕はょゎょゎえんじにあかつQiita自体初めて投稿するので期待せず生暖かい目でじっとりと見てくださると幸いです。

作ったもの

gif
このように、アイテムを入手した時に「〇〇を手に入れた」とログを表示して、一定時間経過後フェードアウトしていくUIを作ってみました。
また、文字数が長い場合改行されるようにしてみました。

ちなみにこれは今作っている脱出ゲームのようなサムシングのために作ったものなので、関係ないUIが映り込んでますが気にしないでください(?)

実行環境

  • Unity 2019.2.14f1

作り方

前提となるオブジェクトやコンポーネントを配置

892742318081356.png
このようにCanvasの子に空のゲームオブジェクト、その子にTextを任意の数配置します。
配置したら、空のゲームオブジェクトにVertical Layout GroupとContent Size Fitterコンポーネントを追加します。
42456234356410.png
コンポーネントの設定は画像の通りです。
Spacingは子オブジェクトの間隔なので任意の値にしてください。
またChild Alignmentは子のTextの文字の開始場所になるので、これも適当に設定してください。
位置は適当に調整してください。また、Widthを変更することでTextの文字が改行される位置を調整することができます。

Text達は特に変更する必要はありません。必要に応じてFont Sizeなどを変更してください。(ただし、Horizontal Overflowの設定をOverflowにすると改行されなくなります。)

スクリプトを書く

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

public class OutputLog : MonoBehaviour
{
    private int textCount; // 子オブジェクト(Text)の数を格納
    private Text[] logTexts;
    private textProperty[] textProperty;
    [SerializeField] float fadeoutSpeed; // フェードアウトの速度(0~1以内)
    [SerializeField] float fadeoutStartTime; // フェードアウトが始まる時間

    void Start()
    {
        textCount = transform.childCount;
        logTexts = new Text[textCount];
        textProperty = new textProperty[textCount];
        for(int i = 0; i < textCount; i++)
        {
            logTexts[i] = transform.GetChild(i).GetComponent<Text>();
            Color color = logTexts[i].color;
            logTexts[i].color = new Color(color.r, color.g, color.b, 0);
            textProperty[i].alfa = 0;
            textProperty[i].elapsedTime = 0;
        }
    }

    void FixedUpdate()
    {
        // 一番上に来たテキストのフェードアウトが始まってない場合開始
        if (textProperty[0].alfa == 1)
        {
            textProperty[0].elapsedTime = fadeoutStartTime;
        }
        // 経過時間のカウントやフェードアウトの処理
        for (int i = textCount - 1; i >= 0; i--)
        {
            if (textProperty[i].alfa > 0)
            {
                if (textProperty[i].alfa == 1)
                {
                    textProperty[i].elapsedTime += Time.deltaTime;
                }

                if (textProperty[i].elapsedTime >= fadeoutStartTime)
                {
                    textProperty[i].alfa -= fadeoutSpeed;
                }

                if (textProperty[i].alfa < 0)
                {
                    textProperty[i].alfa = 0;
                }
                Color color = logTexts[i].color;
                logTexts[i].color = new Color(color.r, color.g, color.b, textProperty[i].alfa);
            }
            else
            {
                break;
            }
        }
    }

    public void Hoge(string name) // ログを流したい時に呼び出す
    {
        // テキスト、透明度、経過時間を一つ上にずらす
        if (textProperty[textCount - 1].alfa > 0)
        {
            for (int i = 0; i < textCount - 1; i++)
            {
                logTexts[i].text = logTexts[i + 1].text;
                textProperty[i].alfa = textProperty[i + 1].alfa;
                textProperty[i].elapsedTime = textProperty[i + 1].elapsedTime;
            }
        }
        // 一番下のテキストを変更して表示、経過時間をリセット
        logTexts[textCount - 1].text = name + "を手に入れた"; // ここの文章を変えることで流れるメッセージが変わります
        textProperty[textCount - 1].alfa = 1f;
        textProperty[textCount - 1].elapsedTime = 0f;
    }
}
// テキストごとに透明度と表示されてからの経過時間を格納する
struct textProperty
{
    public float alfa;
    public float elapsedTime;
}

これを空のゲームオブジェクト(Text達の親)につければ完成です。
後はログを流したいタイミングでHogeメソッドを呼び出せばOKです。
fadeoutSpeedとfadeoutStartTimeはそれぞれフェードアウトの速度とフェードアウトが始まる時間なので、インスペクタから設定してください。なおfadeoutSpeedは0~1の範囲内にしてください。(まあ0だとフェードアウトしなくなりますが)

終わりに

いかがでしたか。
まあ本当にいかがでしたかサイトレベルの内容なんですが、N高ガチプロ勢から突っ込みをもらわないよう祈りたいと思います。っょっょえんじにあ怖いめう><
実際突っ込みどころは色々あると思うので、そこはお手柔らかにお願いします…(怖いとか言ってますが改善点あったらガンガン言ってください)(関係ないですが変数とかの命名苦手です)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away