はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】コンピューターのチカチカする奴をTextMeshProで再現してみた

はじめに

コンピューターの画面で以下の画像のようなチカチカする奴ってありますよね。

f:id:hanaaaaaachiru:20190731180143g:plain

それをTextMeshPro UGUIを用いて再現してみました。

では早速みていきましょう。

スクリプト

前提としてTextMeshProUniRxが必要となります

TextMeshProPackageManagerから、UniRxAssetStoreからダウンロードしてください。


TMP_Computer.cs
using System;
using System.Linq;
using System.Collections.Generic;
using TMPro;
using UniRx;

public static class TMP_Computer
{
    private const double TIMER_INTERVAL = 1;

    private static List<TextData> _textdata = null;

    private static IDisposable _timer = null;

    public static void Subscribe(TextMeshProUGUI tmp)
    {
        if (_textdata == null) Initialize();
        _textdata.Add(new TextData(tmp));
    }

    public static void UnSubscribe(TextMeshProUGUI tmp)
    {
        var target = _textdata.Where(t => t.TMP == tmp)
            .FirstOrDefault();

        if (target == null) return;

        target.Destroy();
        _textdata.Remove(target);

        if (_textdata.Count == 0) OnCompleted();
    }

    private static void Initialize()
    {
        _textdata = new List<TextData>();
        _timer = Observable.Interval(TimeSpan.FromSeconds(TIMER_INTERVAL))
            .Subscribe(o =>
            {
                _textdata.ForEach(t => t.ChangeDisplay());
            });
    }

    private static void OnCompleted()
    {
        _textdata = null;
        _timer.Dispose();
        _timer = null;
    }

    public class TextData
    {
        public TextMeshProUGUI TMP { get; }
        private bool _isDisplayed;
        public bool IsDisplayed
        {
            private set
            {                
                if (value)
                {
                    if (!TMP.text.EndsWith("_")) TMP.text += '_';
                }
                else
                {
                    TMP.text = TMP.text.TrimEnd('_');
                }
                _isDisplayed = value;
            }
            get => _isDisplayed;
        }

        public TextData(TextMeshProUGUI tmp)
        {
            TMP = tmp;
            IsDisplayed = false;
        }

        public void ChangeDisplay() => IsDisplayed = !IsDisplayed;

        public void Destroy() => IsDisplayed = false;
    }
}

使い方

using UnityEngine;
using System.Collections;
using TMPro;

public class Test : MonoBehaviour
{
    [SerializeField] private TextMeshProUGUI _text;
    private IEnumerator Start()
    {
        TMP_Computer.Subscribe(_text);          //テキストに"_"をチカチカさせる
        yield return new WaitForSeconds(5);     //5秒間待つ
        TMP_Computer.UnSubscribe(_text);        //チカチカを終了する(最後に忘れずにする)
    }
}

f:id:hanaaaaaachiru:20190802161145p:plain

さいごに

もしTextMeshProで用いたい場合は、コードでTextMeshProUGUIと書いてあるところをTextMeshProに変えれば動くはずです。

またUnSubscribeを忘れると、無駄にメモリ等を食ってしまうので忘れずに使い終わったらしてください。