vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

【Unity】DOTweenで画像を点滅させるメモ

はじめに

必要になったのでメモ。

やりたいこと

  • 何かの操作をトリガーに、一定時間で Image を Alpha 0 -> Image のデフォルトの Alpha 値に戻すアニメーションを実行
  • 何かの操作をトリガーに、一定時間で Image の Scale を大きくするアニメーションを実行

今回は DOTween を使用しました。

http://dotween.demigiant.com/index.php

コード

using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

public class BlinkController : MonoBehaviour
{
    // 点滅対象.
    public Image Limited;

    // アニメーション開始のトリガー.
    public Button StartButton;

    private const float AnimeTimeSec = 1.0f;
    private const int AnimeRepeatCount = 3;
    private int count;
    private float defaultAlpha;
    private Vector3 defaultScale;
    private Vector3 largeScale;

    private void Start ()
    {
        defaultAlpha = Limited.color.a;
        defaultScale = Limited.rectTransform.localScale;

        largeScale = new Vector3(
            defaultScale.x * 1.2f,
            defaultScale.y * 1.2f,
            defaultScale.z * 1.2f);

        StartButton.onClick.AddListener(() =>
        {
            // 実行中のアニメーションをリセット.
            count = 0;
            DOTween.Clear();
            // 点滅アニメーション.
            StartBlinking();
        });
    }

    private void StartBlinking()
    {
        var startColor = Limited.color;
        startColor.a = 0f;
        Limited.color = startColor;

        Limited.rectTransform.localScale = defaultScale;

    // 引数1: アニメーション完了後の Scale 引数2: アニメーションの実行時間.
        Limited.rectTransform.DOScale(largeScale, AnimeTimeSec)
            .SetEase(Ease.Linear);

    // 引数1: Alpha 値変更対象の Color(Getter) 引数2: Setter.
    // 引数3: アニメーション完了後の Alpha 引数4: アニメーションの実行時間.
        DOTween.ToAlpha(() => Limited.color, value => Limited.color = value, defaultAlpha, AnimeTimeSec)
            .SetEase(Ease.Linear)
            .OnComplete(() =>
            {
                count += 1;
                if (count < AnimeRepeatCount)
                {
                    // 一定回数繰り返し.
                    StartBlinking();
                }
                else
                {
          // 完了後の処理が不要なら Else ごと削除しても OK.
                    Debug.Log("finished");
                }
            });
    }
}

非常にシンプルにできてよいですね。

タイマーを追加する

ついでに、ボタンが押されたらタイマーを起動して、一定時間ごとにアニメーションを繰り返すようにしてみます。

using System.Diagnostics;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
using Debug = UnityEngine.Debug;

public class BlinkController : MonoBehaviour
{
    public Image Limited;

    public Button StartButton;
    // アニメーション、タイマーをリセット.
    public Button StopAllButton;

    private const long RepeatAnimeTimeMillisec = 5000L;
    private const float AnimeTimeSec = 1.0f;
    private const int AnimeRepeatCount = 3;
    private int count;
    private float defaultAlpha;
    private Vector3 defaultScale;
    private Vector3 largeScale;

    private bool timerSet;

    private readonly Stopwatch watch = new Stopwatch();

    private void Start ()
    {
        defaultAlpha = Limited.color.a;
        defaultScale = Limited.rectTransform.localScale;

        largeScale = new Vector3(
            defaultScale.x * 1.2f,
            defaultScale.y * 1.2f,
            defaultScale.z * 1.2f);

        StartButton.onClick.AddListener(Play);
        StopAllButton.onClick.AddListener(StopAll);
    }

    private void Update()
    {
        if (timerSet)
        {
            if (watch.ElapsedMilliseconds > RepeatAnimeTimeMillisec)
            {
        // 一定時間が経過したらアニメーション開始.
                Play();
            }
        }
    }
  // タイマーの開始は最初のアニメーション実行後とする.
    private void Play()
    {
        timerSet = false;
        watch.Stop();
        count = 0;
        DOTween.Clear();
        StartBlinking();
    }
  // アニメーション、タイマーをリセット.
    private void StopAll()
    {
        timerSet = false;
        watch.Stop();
        count = 0;
        DOTween.Clear();
    }
    private void StartBlinking()
    {
        var startColor = Limited.color;
        startColor.a = 0f;
        Limited.color = startColor;

        Limited.rectTransform.localScale = defaultScale;

        Limited.rectTransform.DOScale(largeScale, AnimeTimeSec)
            .SetEase(Ease.Linear);
        DOTween.ToAlpha(() => Limited.color, value => Limited.color = value, defaultAlpha, AnimeTimeSec)
            .SetEase(Ease.Linear)
            .OnComplete(() =>
            {
                count += 1;
                if (count < AnimeRepeatCount)
                {
                    StartBlinking();
                }
                else
                {
                    // アニメーションが終わったらタイマー起動.
                    timerSet = true;
                    watch.Reset();
                    watch.Start();
                }
            });
    }
}

参照