DOTweenを用いたローディングアニメーション【円編】

プログラム実装

何らかの処理でユーザーを待たせる場合は、プログレスバーローディングアニメーションを表示することが有効です。

 

今回はローディングアニメーションについて、UnityのDOTweenを用いていくつか実装してみました。

DOTweenはUnityのAssetStoreで入手できる無料のアセットです。

 

何かと便利になっている有料版もありますが、まずは無料版でも全く問題ないと思います。

(個人的には有料版がおすすめですが)

 

多くの種類が考えられるので、今回は円を用いたローディングアニメーションのみとしました。

後日【円編】以外も記事にするかもしれません。

 

円を用いたローディングアニメーション一覧

今回はこの8つを作ってみました。

 

似たようなものもありますが、どれも円のみを用いたローディングアニメーションです。

ひとつずつコードを紹介していきます。

 

最初の例でUnity上での使用方法を簡単に説明しています。

それ以降のアニメーションでも同様に行ってください。

 

ぐるぐる回るアニメーション

8つの円が円形に並んでいて、順番にフェードしていくアニメーション。

最もローディングアニメーションらしいアニメーションと言っても良いかもしれません。

 

コードはこちら。

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

public class LoadingAnimPlayer : MonoBehaviour
{
    private const float DURATION = 1f;

    void Start()
    {
        Image[] circles = GetComponentsInChildren();
        for (var i = 0; i < circles.Length; i++)
        {
            var angle = -2 * Mathf.PI * i / circles.Length;
            circles[i].rectTransform.anchoredPosition = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * 50f;
            circles[i].DOFade(0f, DURATION).SetLoops(-1, LoopType.Yoyo).SetDelay(DURATION * i / circles.Length);
        }
    }
}

 

このスクリプトを親オブジェクトにアタッチし、その子オブジェクトに円のImageを8つ置いておきます。

 

円のImageは適当に配置しておいて大丈夫です。

スクリプト内で初期配置するようにしています。

今回は円のImageを事前に生成しておく方法をとりましたが、Imageの生成もスクリプト内でやってしまっても良いかもしれません。

 

あとはエディタ実行するだけで、ローディングアニメーションが再生されます。

 

ちなみに円の数は8つではなくても可能です。

これ以降のアニメーションも、自由に子オプジェクトの数を変えられるものがほとんどです。

 

横並びで順番に跳ねるアニメーション

 

コードはこちら。

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

public class LoadingAnimPlayer : MonoBehaviour
{
    private const float DURATION = 1f;

    void Start()
    {
        Image[] circles = GetComponentsInChildren();
        for (var i = 0; i < circles.Length; i++)
        {
            circles[i].rectTransform.anchoredPosition = new Vector2((i - circles.Length / 2) * 50f, 0);
            Sequence sequence = DOTween.Sequence()
                .SetLoops(-1, LoopType.Restart)
                .SetDelay((DURATION / 2) * ((float)i / circles.Length))
                .Append(circles[i].rectTransform.DOAnchorPosY(30f, DURATION / 4))
                .Append(circles[i].rectTransform.DOAnchorPosY(0f, DURATION / 4))
                .AppendInterval((DURATION / 2) * ((float)(1 - i) / circles.Length));
            sequence.Play();
        }
    }
}

 

広がって回って集まるアニメーション

 

コードはこちら。

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

public class LoadingAnimPlayer : MonoBehaviour
{
    private const float DURATION = 0.5f;

    void Start()
    {
        Image[] circles = GetComponentsInChildren();
        for (var i = 0; i < circles.Length; i++)
        {
            var angle = -2 * Mathf.PI * i / circles.Length;
            circles[i].rectTransform.anchoredPosition = Vector2.zero;
            Sequence sequence = DOTween.Sequence()
                .SetLoops(-1, LoopType.Yoyo)
                .AppendInterval(DURATION / 4)
                .Append(circles[i].rectTransform.DOAnchorPos(new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * 50f, DURATION / 2))
                .AppendInterval(DURATION / 4);
            sequence.Play();
        }

        Sequence sequenceParent = DOTween.Sequence()
                .SetLoops(-1, LoopType.Incremental)
                .Append(transform.DOLocalRotate(Vector3.forward * (180f / circles.Length), DURATION / 4))
                .AppendInterval(DURATION / 2)
                .Append(transform.DOLocalRotate(Vector3.forward * (180f / circles.Length), DURATION / 4));
        sequenceParent.Play();
    }
}

 

横並びで順番に拡大縮小するアニメーション

 

コードはこちら。

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

public class LoadingAnimPlayer : MonoBehaviour
{
    private const float DURATION = 1f;

    void Start()
    {
        Image[] circles = GetComponentsInChildren();
        for (var i = 0; i < circles.Length; i++)
        {
            circles[i].rectTransform.anchoredPosition = new Vector2((i - circles.Length / 2) * 50f, 0);
            Sequence sequence = DOTween.Sequence()
                .SetLoops(-1, LoopType.Restart)
                .SetDelay((DURATION / 2) * ((float)i / circles.Length))
                .Append(circles[i].rectTransform.DOScale(1.5f, DURATION / 4))
                .Append(circles[i].rectTransform.DOScale(1f, DURATION / 4))
                .AppendInterval((DURATION / 2) * ((float)(1 - i) / circles.Length));
            sequence.Play();
        }
    }
}

 

横並びで順番にフェードするアニメーション

 

コードはこちら。

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

public class LoadingAnimPlayer : MonoBehaviour
{
    private const float DURATION = 1f;

    void Start()
    {
        Image[] circles = GetComponentsInChildren();
        for (var i = 0; i < circles.Length; i++)
        {
            circles[i].rectTransform.anchoredPosition = new Vector2((i - circles.Length / 2) * 50f, 0);
            Sequence sequence = DOTween.Sequence()
                .SetLoops(-1, LoopType.Restart)
                .SetDelay((DURATION / 2) * ((float)i / circles.Length))
                .Append(circles[i].DOFade(0f, DURATION / 4))
                .Append(circles[i].DOFade(1f, DURATION / 4))
                .AppendInterval((DURATION / 2) * ((float)(1 - i) / circles.Length));
            sequence.Play();
        }
    }
}

 

回転してフェードするアニメーション

 

コードはこちら。

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

public class LoadingAnimPlayer : MonoBehaviour
{
    private const float DURATION = 0.5f;

    void Start()
    {
        Image[] circles = GetComponentsInChildren();
        for (var i = 0; i < circles.Length; i++)
        {
            var angle = 2 * Mathf.PI * i / circles.Length;
            circles[i].rectTransform.anchoredPosition = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * 50f;
            Sequence sequence = DOTween.Sequence()
                .SetLoops(-1, LoopType.Yoyo)
                .AppendInterval(DURATION / 4)
                .Append(circles[i].DOFade(0f, DURATION / 2))
                .AppendInterval(DURATION / 4);
            sequence.Play();
        }

        Sequence sequenceParent = DOTween.Sequence()
                .SetLoops(-1, LoopType.Incremental)
                .Append(transform.DOLocalRotate(Vector3.forward * (360f / circles.Length), DURATION / 4))
                .AppendInterval(DURATION / 2)
                .Append(transform.DOLocalRotate(Vector3.forward * (360f / circles.Length), DURATION / 4));
        sequenceParent.Play();
    }
}

 

格子状に並んだ円がランダムフェードするアニメーション

 

コードはこちら。

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

public class LoadingAnimPlayer : MonoBehaviour
{
    private const float DURATION = 1f;

    void Start()
    {
        Image[] circles = GetComponentsInChildren();
        var size = (int)Mathf.Sqrt(circles.Length);
        for (var i = 0; i < circles.Length; i++)
        {
            var x = i % size - (float)(size - 1) / 2;
            var y = (int)(i / size) - (float)(size - 1) / 2;
            circles[i].rectTransform.anchoredPosition += new Vector2(x, y) * 50f;
            circles[i].DOFade(0f, DURATION / 2).SetLoops(-1, LoopType.Yoyo).SetDelay(Random.Range(0f, DURATION));
        }
    }
}

 

このアニメーションに関しては、円の数は4、9、16・・・などn^2個だときれいに見えると思います。

 

3D空間を回転するアニメーション

 

コードはこちら。

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

public class LoadingAnimPlayer : MonoBehaviour
{
    private const float DURATION = 1f;

    void Start()
    {
        Image[] circles = GetComponentsInChildren();
        for (var i = 0; i < circles.Length; i++)
        {
            var angle = 2 * Mathf.PI * i / circles.Length;
            circles[i].rectTransform.anchoredPosition3D = new Vector3(Mathf.Sin(angle), 0, Mathf.Cos(angle)) * 50f;
            circles[i].rectTransform.DOLocalRotate(-Vector3.up * (360f / circles.Length), DURATION).SetLoops(-1);
            circles[i].color = new Color(1f, 1f, 1f, 0.7f);
        }
        GetComponent().DOLocalRotate(Vector3.up * (360f / circles.Length), DURATION).SetLoops(-1);
    }
}

 

3D空間上のY軸を中心に回っているような感じのアニメーションです。

3つが一番きれいに見える気がします。

 

まとめ

円のみを使ったローディングアニメーションの例と、UnityのDOTweenを使った実装方法を紹介しました。

 

いろいろとカスタマイズ可能なので、そのゲームに合ったローディングアニメーションに作り変えたりしてみても良いのではないでしょうか。

コメント

タイトルとURLをコピーしました