概要
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.");
});
}
}