PrimeTween学习笔记
前言
之前一直用的是DoTween,在看一个DoTween的B站视频时,看到评论区有人提到了PrimeTween,且提到了“高性能”,因此就找到了Github上的仓库,被其高性能(是DoTween的几倍性能)与“0GC”吸引,于是通读了文档并简单实践了一下。下面有针对性的记录一些个人感觉印象比较深刻,以及可能比较常用的点:
Tween
- 使用
Tween.
来调用Tween的静态方法以创建一个Tween动画 - Tween是一个结构体,可以用变量接收并查看Tween的状态或控制其行为,例如:
1
2
3
4
5Tween m_Tween = Tween.PositionX(...);
if(m_Tween.isAlive && m_Tween.isPaused)
{
m_Tween.Stop();
} - Tween几乎可以驱动任何Unity中元素的变化,如UI,UIToolKit,Material,Camera,Transform等
- PrimeTween中不支持对Tween的正向/逆向播放,因此如果想实现类似于窗口的弹出/收回,UI组件的渐隐/渐现的”对称“效果,需要停止当前并用新的Tween来播放新的对称动画。例如:
1
2
3
4[ ] RectTransform window;
public void SetWindowOpened(bool isOpened) {
Tween.UIAnchoredPositionY(window, endValue: isOpened ? 0 : -500, duration: 0.5f);
}
CallBack
- Tween支持类似DoTween的回调,例如:
1
Tween.PositionX(...).OnComplete(()=>Debug.Log("Tween Complete!"))
- 但需要注意的是,这种情况会引入匿名函数的引用带来GC,解决方法如下:
- 使用一个具体的参数来表示该委托,例如:
1
2
3
4Tween.PositionX(...)
.OnComplete(target : this, target.Log("Tween Complete!"));
// 注意这里的target表示该脚本自身,所以要自身实现Log方法
// 应该target参数处传其他引用进去也可以的(TODO 测试下)
- 使用一个具体的参数来表示该委托,例如:
Delay
- 实用且常用的延迟执行,例如:
1
Tween.Delay(duration: 1f, ()=>Debug.Log("xxx"));
Cycles
- 实现动画循环,例如:
1
Tween.PositionY(transform, endValue: 10, duration: 0.5f, cycles: 2, cycleMode: CycleMode.Yoyo);// 循环2次,Yoyo(来回模式)
Sequence
- 实现一组动画与回调的播放控制,支持重叠播放,并行播放,顺序播放等。例如:
1
2
3
4
5
6
7
8
9
10
11Sequence.Create(cycles: 10, CycleMode.Yoyo)
// PositionX and Scale tweens are 'grouped', so they will run in parallel
.Group(Tween.PositionX(transform, endValue: 10f, duration: 1.5f))
.Group(Tween.Scale(transform, endValue: 2f, duration: 0.5f, startDelay: 1))
// Rotation tween is 'chained' so it will start when both previous tweens are finished (after 1.5 seconds)
.Chain(Tween.Rotation(transform, endValue: new Vector3(0f, 0f, 45f), duration: 1f))
.ChainDelay(1)
.ChainCallback(() => Debug.Log("Sequence cycle completed"))
// Insert color animation at time of '0.5' seconds
// Inserted animations overlap with other animations in the sequence
.Insert(atTime: 0.5f, Tween.Color(image, Color.red, duration: 0.5f)); - 除了Sequnce来实现一组有序动画的控制,PrimeTween还支持协程与异步
Coruntine
- 在协程中使用
.ToYieldInstruction()
来等待动画完成后,继续执行后面的代码。类似于等待一段时间的条件,只不过这里的条件是当前动画完成,例如:1
2
3
4
5
6
7
8IEnumerator Coroutine() {
Tween.PositionX(transform, endValue: 10f, duration: 1.5f);
yield return Tween.Scale(transform, 2f, 0.5f, startDelay: 1).ToYieldInstruction();
yield return Tween.Rotation(transform, new Vector3(0f, 0f, 45f), 1f).ToYieldInstruction();
// Non-allocating alternative to 'yield return new WaitForSeconds(1f)'
yield return Tween.Delay(1).ToYieldInstruction();
Debug.Log("Sequence completed");
}
Async/Await
- PrimeTween支持C#中的async/await语法,从而使用同步的形式编写异步代码,有效避免陷入“地狱回调”。注意这里并不是通过多线程实现的。用法举例:
1
2
3
4
5
6
7
8
9async void AsyncMethod() {
Tween.PositionX(transform, endValue: 10f, duration: 1.5f);
await Tween.Scale(transform, endValue: 2f, duration: 0.5f, startDelay: 1);
await Tween.Rotation(transform, endValue: new Vector3(0f, 0f, 45f), duration: 1f);
// Non-allocating alternative to 'await Task.Delay(1000)' that doesn't use 'System.Threading'
// Animations can be awaited on all platforms, even on WebGL
await Tween.Delay(1);
Debug.Log("Sequence completed");
}
Custom tweens
- PrimeTween中支持”自定义动画“,支持的值类型有
float, Color, Vector2/3/4, Quaternion, and Rect
,可以针对以上值实现自定义的变化,例如:1
2
3
4
5
6
7
8float floatField;
Color colorField;
// Animate 'floatField' from 0 to 10 in 1 second
Tween.Custom(0, 10, duration: 1, onValueChange: newVal => floatField = newVal);
// Animate 'colorField' from white to black in 1 second
Tween.Custom(Color.white, Color.black, duration: 1, onValueChange: newVal => colorField = newVal);
TimeScale
- PrimeTween可以在不改变Unity内置TimeScale的情况下实现指定动画的倍速控制,或调整全局倍速,例如:
1
2
3
4
5
6// 平滑变速指定Tween或Sequence
Tween.TweenTimeScale(Tween/Sequence tween, ...)
// 全局倍速控制(改变Unity的TimeScale)
Tween.GlobalTimeScale(...)
Speed-based anim
- 使用
Tween._AtSpeed
实现按指定速度来匀速执行动画,PrimeTween会自动按指定的速度计算时间。 - 需要注意的是,当需要链式
.Chain
使用基于速度的动画时,需要指定每段动画的开始位置,例如:1
2
3Tween.LocalPositionAtSpeed(transform, endValue: midPos, speed)
// Set 'startValue: midPos' to continue the movement from the 'midPos' instead of the initial 'transform.position'
.Chain(Tween.LocalPositionAtSpeed(transform, startValue: midPos, endValue: endPos, speed));
Debugging tweens
- 在运行时,PrimeTween会维护一
PrimeTweenManager
在DonDestoryOnLoad中,可以在Inspector面板中点击查看所有Tween的状态。
Migrating from DoTween to PrimeTween
- 支持一键转化,也可以对照API表格手动更新
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.