LoginSignup
37
32

More than 3 years have passed since last update.

UniRxでDOTweenをObservableにする

Last updated at Posted at 2019-02-02

概要

DOTweenをObservableにしました。
すべてのアニメーションの完了を待ってから何かしたいといった場合に、
Observable化されていると、何かと便利です。

DOTween

無料版と有料版があり、それぞれアセットストアからDLできます。
DOTween (HOTween v2)
DOTweenPro

使用バージョン

DOTweenPro v1.0.075

コード

DOTweenExtensions.cs
using UniRx;
using System;
using DG.Tweening;

static public partial class DOTweenExtensions
{
    static public IObservable<Tween> OnCompleteAsObservable(this Tween tweener)
    {
        return Observable.Create<Tween>(o =>
        {
            tweener.OnComplete(() =>
            {
                o.OnNext(tweener);
                o.OnCompleted();
            });
            return Disposable.Create(() =>
            {
                tweener.Kill();
            });
        });
    }

    static public IObservable<Sequence> PlayAsObservable(this Sequence sequence)
    {
        return Observable.Create<Sequence>(o =>
        {
            sequence.OnComplete(() =>
            {
                o.OnNext(sequence);
                o.OnCompleted();
            });
            sequence.Play();
            return Disposable.Create(() =>
            {
                sequence.Kill();
            });
        });
    }

#if true //DOTweenPro Extensions
    static public IObservable<DOTweenAnimation> DOPlayAsObservable(
        this DOTweenAnimation animation,
        bool rewind = false)
    {
        return Observable.Create<DOTweenAnimation>(o =>
        {
            if (rewind) animation.DORewind();

            animation.tween.OnComplete(() =>
            {
                o.OnNext(animation);
                o.OnCompleted();
            });
            animation.DOPlay();
            return Disposable.Empty;
        });
    }

    static public IObservable<DOTweenAnimation> DOPlayByIdAsObservable(
        this DOTweenAnimation animation,
        string id,
        bool rewind = false)
    {
        return Observable.Create<DOTweenAnimation>(o =>
        {
            if (rewind) animation.DORewind();

            animation.tween.OnComplete(() =>
            {
                o.OnNext(animation);
                o.OnCompleted();
            });
            animation.DOPlayById(id);
            return Disposable.Empty;
        });
    }

    static public IObservable<DOTweenAnimation> DOPlayAllByIdAsObservable(
        this DOTweenAnimation animation,
        string id,
        bool rewind = false)
    {
        return Observable.Create<DOTweenAnimation>(o =>
        {
            if (rewind) animation.DORewind();

            animation.tween.OnComplete(() =>
            {
                o.OnNext(animation);
                o.OnCompleted();
            });
            animation.DOPlayAllById(id);
            return Disposable.Empty;
        });
    }

    static public IObservable<DOTweenAnimation> DORestartAsObservable(
        this DOTweenAnimation animation,
        bool fromHere = false)
    {
        return Observable.Create<DOTweenAnimation>(o =>
        {
            animation.tween.OnComplete(() =>
            {
                o.OnNext(animation);
                o.OnCompleted();
            });
            animation.DORestart(fromHere);
            return Disposable.Empty;
        });
    }

    static public IObservable<DOTweenAnimation> DORestartByIdAsObservable(
        this DOTweenAnimation animation,
        string id)
    {
        return Observable.Create<DOTweenAnimation>(o =>
        {
            animation.tween.OnComplete(() =>
            {
                o.OnNext(animation);
                o.OnCompleted();
            });
            animation.DORestartById(id);
            return Disposable.Empty;
        });
    }

    static public IObservable<DOTweenAnimation> DORestartAllByIdAsObservable(
        this DOTweenAnimation animation,
        string id)
    {
        return Observable.Create<DOTweenAnimation>(o =>
        {
            animation.tween.OnComplete(() =>
            {
                o.OnNext(animation);
                o.OnCompleted();
            });
            animation.DORestartAllById(id);
            return Disposable.Empty;
        });
    }
#endif //DOTweenPro Extensions
}

DOTweenProでのみ使用可能なDOTweenAnimationを使用しているコードは
if~endifで囲っています。無料版を使用している場合はDOTweenAnimationが使用不可なので、
falseにしてください。

使用例

DOLocalMove

        this.transform.DOLocalMove(new Vector3(-200f, 0f, 0f), 1f)
            .OnCompleteAsObservable()
            .Subscribe(_ => 
            {
                Debug.Log("Completed.");
            })
            .AddTo(this);

シーケンス


        // シーケンス
        var sequence = DOTween.Sequence();
        sequence.Append(anim.tween);
        sequence.PlayAsObservable().Subscribe(_ =>
        {
            Debug.Log("Complete Sequence.");
        })
        .AddTo(this);

Observable.WhenAllですべてのアニメの待機完了待ち


    [SerializeField] DOTweenAnimation[] animations;

    void Start()
    {
        Observable.WhenAll(animations.Select(x => x.DOPlayAsObservable(rewind)))
        .Subscribe(x =>
        {
            Debug.Log("Completed.");
        });
        .AddTo(this);
    }

AsyncMessageBrokerでアニメの待機完了待ち

他にもMessageBrokerの非同期版であるAsyncMessageBrokerで、
送り手がメッセージをPublishして誰がReceiveしているかわからないけど完了するまで
送り手を待機させるといった、疎結合な非同期処理も可能です。

    public class AnimEvent {}

    // 受け手
    public class SampleReceiver : MonoBehaviour
    {
        [SerializeField] DOTweenAnimation anim;

        void Awake()
        {
            AsyncMessageBroker.Default.Subscribe<AnimEvent>(_ =>
                bool rewind = true;
                anim.DOPlayByIdAsObservable("in", rewind)
            ).AddTo(this);
        }
    }

    // 送り手
    public class SamplePublisher : MonoBehaviour
    {
        void Start()
        {
            AsyncMessageBroker.Default.PublishAsync<AnimEvent>(new AnimEvent()).Subscribe(_ =>
            {
                Debug.Log("Publish Completed.");
            });
        }
    }
37
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
32