using System; using System.Collections; using UniRx; using UnityEngine; using System.Threading; namespace UniRx { public static partial class CustomObservable { /// /// Tween in seconds /// public static IObservable Tween( Vector2 from, Vector2 to, float seconds ) { Vector2 delta = to - from; Func lerpFunc = ( progress ) => { return from + (delta * progress); }; return UniRx.Observable.FromMicroCoroutine(( observer, cancellationToken ) => TweenEveryCycleCore(observer, from, to, seconds, lerpFunc, cancellationToken), FrameCountType.Update); } public static IObservable Tween( Vector3 from, Vector3 to, float seconds ) { Vector3 delta = to - from; Func lerpFunc = ( progress ) => { return from + (delta * progress); }; return UniRx.Observable.FromMicroCoroutine(( observer, cancellationToken ) => TweenEveryCycleCore(observer, from, to, seconds, lerpFunc, cancellationToken), FrameCountType.Update); } public static IObservable Tween( float from, float to, float seconds ) { float delta = to - from; Func lerpFunc = ( progress ) => { return from + (delta * progress); }; return UniRx.Observable.FromMicroCoroutine(( observer, cancellationToken ) => TweenEveryCycleCore(observer, from, to, seconds, lerpFunc, cancellationToken), FrameCountType.Update); } public static IObservable Tween( Quaternion from, Quaternion to, float seconds ) { Func lerpFunc = ( progress ) => { return Quaternion.Lerp(from, to, progress); }; return UniRx.Observable.FromMicroCoroutine(( observer, cancellationToken ) => TweenEveryCycleCore(observer, from, to, seconds, lerpFunc, cancellationToken), FrameCountType.Update); } static IEnumerator TweenEveryCycleCore( IObserver observer, T from, T to, float seconds, Func lerpFunc, CancellationToken cancellationToken ) { if( cancellationToken.IsCancellationRequested ) yield break; if( seconds <= 0 ) { observer.OnNext(to); observer.OnCompleted(); yield break; } float totalTime = 0f; observer.OnNext(from); while( true ) { yield return null; if( cancellationToken.IsCancellationRequested ) yield break; totalTime += UnityEngine.Time.deltaTime; if( totalTime >= seconds ) { observer.OnNext(to); observer.OnCompleted(); yield break; } else { float normalizedTime = totalTime / seconds; observer.OnNext(lerpFunc(normalizedTime)); } } } } }