A Day In The Life

とあるプログラマの備忘録

uGUIのテキストを点滅させてみる

Unity の uGUI でテキストをこんな感じに点滅させる方法です。

f:id:glass-_-onion:20161027174139g:plain

Update メソッドに処理を書いても良かったのですが個人的な好みで UniRX を使って実装してみました。Mathf.Sin メソッド(三角関数)を使ってアルファ値を0から1に緩やかに変化させています。

using UnityEngine;
using UnityEngine.UI;
using System;
using System.Collections;
using UniRx;

public class FlashingText : MonoBehaviour
{

  [SerializeField]
  private float angularFrequency = 5f;
  // 30FPS
  static readonly float DeltaTime = 0.0333f;
  private Text text;

  void Start()
  {
    float time = 0.0f;
    text = GetComponent<Text>();
    Observable.Interval(TimeSpan.FromSeconds(deltaTime)).Subscribe(_ =>
      {
        time += angularFrequency * deltaTime;
        var color = text.color;
        color.a = Mathf.Sin(time) * 0.5f + 0.5f;
        text.color = color;
      }).AddTo(this);
  }
}

angularFrequency の値をいじることで点滅のタイミングを調整することができます。

なんで Mathf.Sin(time) * 0.5f + 0.5f なのか

Mathf.Sin メソッドの結果に 0.5 をかけたり足したりしているのはアルファの値を0から1の間で緩やかに変化させるためです。

Mathf.Sin(x)

サイン関数を使うと以下のグラフのように、値は-1から1の間で変化します。 f:id:glass-_-onion:20161027171240p:plain

Mathf.Sin(x) * 0.5

それに0.5をかけて値を-0.5から0.5の間で変化するようにしてから f:id:glass-_-onion:20161027171245p:plain

Mathf.Sin(x) * 0.5 + 0.5

0.5を足すことによって0から1の間に値が収まるようになります。 f:id:glass-_-onion:20161027171250p:plain

Mathf.Abs(Mathf.Sin(time)) じゃダメなの?

値を0から1の間で変化させるだけであれば Mathf.Abs(Mathf.Sin(time)) でも問題なさそうですが、値の変化が滑らかになりません。

Mathf.Abs(Mathf.Sin(time))

Mathf.Abs メソッドを使った場合の値の変化は以下のようになります。0付近の値の変化が急な感じになります。 f:id:glass-_-onion:20161027171256p:plain Mathf.Abs メソッドを使って点滅させると以下のような動きになります。

f:id:glass-_-onion:20161027174140g:plain

微妙な違いですが少し違和感がありますね。