Tween

Anime Rx

AnimeRx - Rx Tween Animation Library for Unity

Created by kyubuns

Task Version! -> kyubuns/AnimeTask

  • IObservable<T> Anime.Play(T from, T to, IAnimator animator)

Installation

Requires Unity 2017.1 or later (5.6でも多分動くけど未確認)
Support .net3.5 and .net4.6

Examples

Basic

sample1

(-5,0,0)から(5,0,0)へ、秒速4mで移動。

Anime.Play(new Vector3(-5f, 0f, 0f), new Vector3(5f, 0f, 0f), Motion.Uniform(4f))
    .Subscribe(x => cube.transform.position = x);
    //.SubscribeToPosition(cube);

Method Chain

sample2

(-5,0,0)から(5,0,0)へ移動した後、(0,3,0)に等速で移動。
この方法を用いた場合、1つ目の移動と2つ目の移動で1フレームの間、値の変化が停止します。
スムーズに移動させるには下記のPathの方法を使用してください。

var animator = Motion.Uniform(5f);
Anime.Play(new Vector3(-5f, 0f, 0f), new Vector3(5f, 0f, 0f), animator)
    .Play(new Vector3(0f, 3f, 0f), animator)
    .SubscribeToPosition(cube);

Easing

sample3

EaseOutQuadで2秒かけて移動。

Anime.Play(new Vector3(-5f, 0f, 0f), new Vector3(5f, 0f, 0f), Easing.OutQuad(TimeSpan.FromSeconds(2f)))
    .SubscribeToPosition(cube);

Sleep

sample10

移動した後、1秒まって再度動き出す。

Anime.Play(new Vector3(-5f, 0f, 0f), new Vector3(0f, 0f, 0f), Easing.OutExpo(TimeSpan.FromSeconds(2f)))
    .Sleep(TimeSpan.FromSeconds(1f))
    .Play(new Vector3(5f, 0f, 0f), Easing.OutExpo(TimeSpan.FromSeconds(2f)))
    .SubscribeToPosition(cube);

Path

sample4

指定したpositionに順番に移動。

var positions = new[]
{
    new Vector3(-5f, 0f, 0f),
    new Vector3(0f, 3f, 0f),
    new Vector3(5f, 0f, 0f),
    new Vector3(0f, -3f, 0f),
    new Vector3(-5f, 0f, 0f),
};

Anime.Play(positions, Easing.InOutSine(TimeSpan.FromSeconds(6f)))
    .SubscribeToPosition(cube);

Combine

sample5

x, y, zの各座標を別々にアニメーションさせて合成。

var x = Anime.Play(-5f, 5f, Easing.InOutSine(TimeSpan.FromSeconds(3f)));

var y = Anime.Play(0f, 3f, Easing.InOutSine(TimeSpan.FromSeconds(1.5f)))
    .Play(0f, Easing.InOutSine(TimeSpan.FromSeconds(1.5f)));

var z = Anime.Stay(0f);

Observable.CombineLatest(x, y, z)
    .SubscribeToPosition(cube);

AnimationCurve

sample11

UnityEngine.AnimationCurveを利用して移動。

Anime.Play(new Vector3(-5f, 0f, 0f), new Vector3(5f, 0f, 0f), Motion.From(curve, TimeSpan.FromSeconds(3f)))
    .SubscribeToPosition(cube);

Extensions

sample6

cube.transform.positionから(3,3,0)へ移動。

cube.transform.position
    .Play(new Vector3(3f, 3f, 0f), Easing.OutBack(TimeSpan.FromSeconds(2f)))
    .SubscribeToPosition(cube);

Circle

sample8

IObservbleを円運動に変換。

Anime.Play(0f, Mathf.PI * 2f, Easing.OutCubic(TimeSpan.FromSeconds(3f)))
    .Select(x => new Vector3(Mathf.Sin(x), Mathf.Cos(x), 0.0f))
    .Select(x => x * 3f)
    .SubscribeToPosition(cube);

Range / Lerp

sample17

途中まで一緒についていく。
特定の範囲だけついていく。

var flow = Anime.Play(Easing.InOutExpo(TimeSpan.FromSeconds(2.5f)))
    .Stop(TimeSpan.FromSeconds(0.5f))
    .Play(1.0f, 0.0f, Easing.InOutExpo(TimeSpan.FromSeconds(2.5f)));

flow
    .Range(0.0f, 0.5f)
    .Lerp(new Vector3(-5f, 0f, 0f), new Vector3(0f, 0f, 0f))
    .SubscribeToPosition(cube2);

flow
    .Lerp(new Vector3(-5f, -1f, 0f), new Vector3(5f, -1f, 0f))
    .SubscribeToPosition(cube);

PlayIn/PlayOut/PlayInOut

sample24

Animationから等速運動に繋げる。

Anime.PlayIn(-5f, 0f, 5f, Easing.InCubic(TimeSpan.FromSeconds(1.0)))
    .SubscribeToPositionX(cube);

Delay

sample18

Observable.Delay in UniRx

var circle = Anime.Play(0f, Mathf.PI * 2f, Easing.OutCubic(TimeSpan.FromSeconds(3f)))
    .Select(x => new Vector3(Mathf.Sin(x), Mathf.Cos(x), 0.0f))
    .Select(x => x * 3f);

circle
    .SubscribeToPosition(cube);

circle
    .Delay(TimeSpan.FromSeconds(0.3f))
    .SubscribeToPosition(cube2);

circle
    .Delay(TimeSpan.FromSeconds(0.55f))
    .SubscribeToPosition(cube3);

Blend

sample20

2つの移動を足し合わせる。

var circle = Anime
    .Play(Mathf.PI, Mathf.PI * 2f * 3f, Easing.InOutSine(TimeSpan.FromSeconds(3f)))
    .Select(x => new Vector3(Mathf.Sin(x), Mathf.Cos(x), 0f));

var straight = Anime
    .Play(-3f, 3f, Easing.InOutSine(TimeSpan.FromSeconds(3f)))
    .Select(x => new Vector3(0f, x, 0f));

Observable.CombineLatest(circle, straight)
    .Sum()
    .SubscribeToPosition(cube);

WhenAll

sample9

WhenAllを使ってアニメーションのタイミングを合わせる。

var leftCube1 = Anime
    .Play(new Vector3(-5f, 0f, 0f), new Vector3(-0.5f, 0f, 0f), Easing.Linear(TimeSpan.FromSeconds(2.5f)))
    .DoToPosition(cube);

var rightCube1 = Anime
    .Play(new Vector3(5f, 0f, 0f), new Vector3(0.5f, 0f, 0f), Easing.OutCubic(TimeSpan.FromSeconds(1f)))
    .DoToPosition(cube2);

var leftCube2 = Anime
    .Play(new Vector3(-0.5f, 0f, 0f), new Vector3(-0.5f, 3f, 0f), Easing.OutCubic(TimeSpan.FromSeconds(1f)))
    .DoToPosition(cube);

var rightCube2 = Anime
    .Play(new Vector3(0.5f, 0f, 0f), new Vector3(0.5f, 3f, 0f), Easing.OutCubic(TimeSpan.FromSeconds(1f)))
    .DoToPosition(cube2);

Observable.WhenAll(leftCube1, rightCube1)
    .ContinueWith(Observable.WhenAll(leftCube2, rightCube2))
    .Subscribe();

Special thanks