Awesome
AnimeRx - Rx Tween Animation Library for Unity
IObservable<T> Anime.Play(T from, T to, IAnimator animator)
Recommend
This is a library from the days when Task was not yet available in Unity.
I recommend using the Task version.
kyubuns/AnimeTask
Instructions
- Import UniTask
- Import AnimeRx
- Package Manager
https://github.com/kyubuns/AnimeRx.git?path=Assets/Plugins/AnimeRx
- UnityPackage
- Package Manager
Examples
Basic
(-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
(-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
EaseOutQuadで2秒かけて移動。
Anime.Play(new Vector3(-5f, 0f, 0f), new Vector3(5f, 0f, 0f), Easing.OutQuad(2f))
.SubscribeToPosition(cube);
Sleep
移動した後、1秒まって再度動き出す。
Anime.Play(new Vector3(-5f, 0f, 0f), new Vector3(0f, 0f, 0f), Easing.OutExpo(2f))
.Sleep(1f)
.Play(new Vector3(5f, 0f, 0f), Easing.OutExpo(2f))
.SubscribeToPosition(cube);
Path
指定した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(6f))
.SubscribeToPosition(cube);
Combine
x, y, zの各座標を別々にアニメーションさせて合成。
var x = Anime.Play(-5f, 5f, Easing.InOutSine(3f));
var y = Anime.Play(0f, 3f, Easing.InOutSine(1.5f))
.Play(0f, Easing.InOutSine(1.5f));
var z = Anime.Stay(0f);
Observable.CombineLatest(x, y, z)
.SubscribeToPosition(cube);
AnimationCurve
UnityEngine.AnimationCurveを利用して移動。
Anime.Play(new Vector3(-5f, 0f, 0f), new Vector3(5f, 0f, 0f), Motion.From(curve, 3f))
.SubscribeToPosition(cube);
Extensions
cube.transform.positionから(3,3,0)へ移動。
cube.transform.position
.Play(new Vector3(3f, 3f, 0f), Easing.OutBack(2f))
.SubscribeToPosition(cube);
Circle
IObservble<float>を円運動に変換。
Anime.Play(0f, Mathf.PI * 2f, Easing.OutCubic(3f))
.Select(x => new Vector3(Mathf.Sin(x), Mathf.Cos(x), 0.0f))
.Select(x => x * 3f)
.SubscribeToPosition(cube);
Range / Lerp
途中まで一緒についていく。
特定の範囲だけついていく。
var flow = Anime.Play(Easing.InOutExpo(2.5f))
.Stop(0.5f)
.Play(1.0f, 0.0f, Easing.InOutExpo(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
Animationから等速運動に繋げる。
Anime.PlayIn(-5f, 0f, 5f, Easing.InCubic(1.0f))
.SubscribeToPositionX(cube);
Delay
Observable.Delay in UniRx
var circle = Anime.Play(0f, Mathf.PI * 2f, Easing.OutCubic(3f))
.Select(x => new Vector3(Mathf.Sin(x), Mathf.Cos(x), 0.0f))
.Select(x => x * 3f);
circle
.SubscribeToPosition(cube);
circle
.Delay(0.3f)
.SubscribeToPosition(cube2);
circle
.Delay(0.55f)
.SubscribeToPosition(cube3);
Blend
2つの移動を足し合わせる。
var circle = Anime
.Play(Mathf.PI, Mathf.PI * 2f * 3f, Easing.InOutSine(3f))
.Select(x => new Vector3(Mathf.Sin(x), Mathf.Cos(x), 0f));
var straight = Anime
.Play(-3f, 3f, Easing.InOutSine(3f))
.Select(x => new Vector3(0f, x, 0f));
Observable.CombineLatest(circle, straight)
.Sum()
.SubscribeToPosition(cube);
WhenAll
WhenAllを使ってアニメーションのタイミングを合わせる。
var leftCube1 = Anime
.Play(new Vector3(-5f, 0f, 0f), new Vector3(-0.5f, 0f, 0f), Easing.Linear(2.5f))
.DoToPosition(cube);
var rightCube1 = Anime
.Play(new Vector3(5f, 0f, 0f), new Vector3(0.5f, 0f, 0f), Easing.OutCubic(1f))
.DoToPosition(cube2);
var leftCube2 = Anime
.Play(new Vector3(-0.5f, 0f, 0f), new Vector3(-0.5f, 3f, 0f), Easing.OutCubic(1f))
.DoToPosition(cube);
var rightCube2 = Anime
.Play(new Vector3(0.5f, 0f, 0f), new Vector3(0.5f, 3f, 0f), Easing.OutCubic(1f))
.DoToPosition(cube2);
Observable.WhenAll(leftCube1, rightCube1)
.ContinueWith(Observable.WhenAll(leftCube2, rightCube2))
.Subscribe();
Loop, Repeat
var disposable = Anime.Play(new Vector3(-5f, 0f, 0f), new Vector3(5f, 0f, 0f), Motion.Uniform(5f))
.Repeat() // infinite loop
.SubscribeToPosition(cube1);
Observable.Timer(TimeSpan.FromSeconds(5)).Subscribe(_ =>
{
Debug.Log("Stop!");
disposable.Dispose();
});
Create your self!
自由に拡張できるインターフェイスが準備されています。
private class ShuffleAnimator : IAnimator
{
private readonly float duration;
public ShuffleAnimator(float duration)
{
this.duration = duration;
}
public float CalcFinishTime(float distance)
{
return duration;
}
public float CalcPosition(float time, float distance)
{
return Random.Range(0f, 1f);
}
}
private void Shuffle()
{
var shuffleX = Anime.Play(-1f, 1f, new ShuffleAnimator(3f));
var shuffleY = Anime.Play(-1f, 1f, new ShuffleAnimator(3f));
Observable.CombineLatest(shuffleX, shuffleY)
.Select(x => new Vector3(x[0], x[1]))
.SubscribeToPosition(cube);
}
Selecting Card
var selectingCard = new ReactiveProperty<Image>(null);
foreach (var card in cards)
{
var cardRectTransform = card.GetComponent<RectTransform>();
card.OnPointerClickAsObservable().Subscribe(x => selectingCard.Value = card).AddTo(card);
var gauge = new ReactiveProperty<float>(0f);
selectingCard
.Select(x =>
{
var isSelecting = x == card;
var target = isSelecting ? 1.0f : 0.0f;
var speed = isSelecting ? 1.0f : 2.0f; // 戻る時は2倍速
card.color = isSelecting ? Color.yellow : Color.white;
return Anime.Play(gauge.Value, target, Motion.Uniform(speed));
})
.Switch()
.Subscribe(x => gauge.Value = x);
gauge
.Subscribe(x =>
{
var p = cardRectTransform.localPosition;
p.y = OutCirc.Calc(x) * SelectingY;
cardRectTransform.localPosition = p;
})
.AddTo(card);
}
Requirements
- Unity 2017.1 or later.
- checked by 2019
- Support .net3.5 and .net4.6
Special thanks
- Inspired by fumobox/TweenRx
- yKimisaki
License
MIT License (see LICENSE)