UTween
是一个 Unity
环境下的插值动画组件,可以通过内置组件快速配置动画,或者通过代码编写动画。
官方交流QQ群:1070645638
UTween 组件采用MIT协议开源:
[OpenUPM]
[Github Link]
[Gitlab Link]
后续功能更新和改进将会持续提交到以上git仓库中,本文内容将不会持续更新。
MaterialPropertyBlock
的高性能材质动画。添加组件,并使用丰富的内置动画和缓动函数:
内置缓动函数:
编辑器实时预览动画,所见即所得:
内置曲线路径编辑器:
/Extension
文件夹中不需要的扩展/Example
目录Assets/Plugins/
中From: 插值的起始值
To: 插值的结束值
Curve: 自定义插值动画曲线,会累乘于缓动函数的计算结果之上
Curve Target: 可选择曲线的运算结果作用在插值因子上还是插值结果数值上
Curve Mode: 可以选择单根曲线作用于整体或者每个轴使用单独的曲线控制
Play Type: 播放类型,可选 Once, Loop, LoopCount, PingPong, PingPongCount
Ease Type: 内置缓动函数类型,默认为线性,可选效果较多,请自行测试。
Loop Count: 循环次数
Duration:: 插值过程持续时间,单位 s
Interval: 重复播放间隔时间,仅 Loop 和 PingPong 模式可用
Speed Based: 基于速度而非时间插值,选中后 Duration 参数作为速度值使用
Start Delay: 插值开始的延迟时间,单位 s
Auto Play: 自动播放的时机,默认 None 不自动播放,可选 Awake, Start, Enable, 如果选择 Enable, 会被多次触发
Update Type: 计算更新的时机,根据动画实际需要调整,默认为 Update, 可选 LateUpdate 和 FixedUpdate
Time Scale: 时间缩放,决定动画是否收到时间缩放变速的影响,可以控制插值动画与游戏过程分离
Self Scale: 自身时间缩放,用于调整动画播放速度,会改变动画的实际运行时长
Time Smooth: 是否使用 Time.smoothDeltaTime,可以让动画不因为帧率波动而抖动,仅在 Time Scale 为 true 时可用
Auto Kill: 播放完后是否自动销毁(仅非无限循环类型播放有效)
Callback: 用于注册插值开始和结束时的回调
实现单一动画效果的最小化组件,对应一组完整的动画参数,每个 Tweener 组件独立运行。
用于管理调度所有的 Tweener 组件,维护所有的 TweenPool,受 Unity MonoBehaviour 生命周期控制,提供 Update / LateUpdate / FixedUpdate 的更新模式。
组件内部对象池,用于 Tweener 组件的回收再利用。
Tweener 的编辑器类,用于在 Inspector 中配置动画,针对不同的 Tweener 提供不同的配置界面。但 TweenAnimation 本身不提供任何逻辑功能,动画的运行任然依赖于 TweenManager,组件只提供数据和配置接口。
基于 ScriptableObject
实现的动画配置资源文件,可以从 TweenAnimation
导入导出,可以通过代码调用以创建动画。
EasyType
的 EaseFunction
中计算。var tween = UTween.Create<TweenValue>();
tween.SetFrom(0f);
tween.SetTo(1f);
tween.SetDuration(2f);
tween.SetFloatCallback(value =>
{
Debug.Log("Value : " + value); }
});
tween.Play();
可以通过 Tween.Create<>()
接口快速创建插值动画,并以链式编程
的方式设置部分属性和回调。
UTween.Create<TweenValue>()
.SetFrom(0f)
.SetTo(1f)
.SetDuration(5f)
.SetUpdateType(UpdateType.Update)
.SetPlayType(PlayType.Once)
.SetEaseType(EaseType.Linear)
.SetTimeScale(false)
.SetPlayCallback(() => { Debug.Log("Play"); })
.SetValueCallback(value => { Debug.Log("Value : " + value); })
.SetStopCallback(() => { Debug.Log("Stp["); })
.Play();
UTween.Position(transform, Vector3.zero, Vector3.one, 1f);
UTween.Scale(transform, Vector3.zero, Vector3.one, 1f);
UTween.Rotation(transform, new Vector3(0, 0, 0), new Vector3(0, 360, 0), 1f);
UTween.Color(image, Color.black, Color.white, 1f);
UTween.Alpha(image, 0f, 1f, 1f);
// 更多API请自行尝试
Transform transform;
transform.Move(Vector3.zero, Vector3.one, 1f);
目前仅包含少量原生组件扩展接口,后续会添加。
顺序插值动画 / 并行插值动画,可以一次性控制一组 Tweener 的状态,但此时子 Tweener 的回调和状态变化都不会触发,转交由上层组件控制。
UTween.GetSequence()
.Append(UTween.Position(SequneceMoveObj, Vector3.zero, Vector3.one, 2f))
.Append(UTween.Position(SequneceMoveObj, Vector3.one, Vector3.up, 2f))
.Append(UTween.Position(SequneceMoveObj, Vector3.up, Vector3.left, 2f))
.Append(UTween.Position(SequneceMoveObj, Vector3.left, Vector3.zero, 2f))
.Play();
UTween.GetParallel()
.Append(UTween.Position(ParallelMoveObj1, new Vector3(2, 0, 0), new Vector3(4, 0, 0), 2f))
.Append(UTween.Position(ParallelMoveObj2, new Vector3(2, 2, 0), new Vector3(4, 2, 0), 2f))
.Play();
使用 SetFromGetter / SetToGetter
方法设置动态获取起点和终点的方法,并确保动画更新在起始点数值更新之后进行,就可以得到一个起点终点动态改变的插值动画:
public float FromValue = 0f;
public float ToValue = 0f;
UTween.Value(0f, 5f, 1f, value => FromValue = value);
UTween.Value(10f, 5f, 1f, value => ToValue = value);
UTween.Create<TweenValue>()
.SetFromGetter(()=> FromValue)
.SetToGetter(()=> ToValue)
.SetDuration(1f)
.SetUpdateType(UpdateType.LateUpdate)
.Play();
通过 Identifier
参数获取一个物体上配置的一个或多个动画组件所生成的动画实例并播放:
var tweeners = gameObject.GetTweeners("Open");
tweeners.Play();
实时获取动画组件或者动画实例开销较高,建议预先缓存 TweenAnimation
组件的引用并在需要时调用。
通过加载的动画配文件创建动画,指定作用对象后播放:
TweenAnimationAsset Asset;
UTween.Create(Asset)
.SetTarget(TweenPosTarget)
.Play();
1.创建自定义缓动类型常量:
[EnumClass("EaseType")]
public static class EaseTypeExtension
{
[EnumProperty("Extension", "Ease Lerp")]
public const int EaseLerp = 10001;
}
2.创建自定义插值类并集成实现 EaseFunction
类型:
public class EaseLerp : EaseFunction
{
public override int Type => EaseTypeExtension.EaseLerp;
public override float Ease(float from, float to, float delta)
{
return Mathf.Lerp(from, to, delta);
}
}
1.创建自定义动画类型常量:
[EnumClass("TweenType")]
public static class TweenTypeExtension
{
[EnumProperty("UI", "Text FontSize")]
public const int TextFontSize = 10001;
}
2.创建自定义插值类并集成实现 Tweener
类型:
[Tweener(TweenTypeExtension.TextFontSize)]
[RequireComponent(typeof(Text))]
public class TweenTextFontSize : TweenFloatBase<Text>
{
public override int Type => TweenTypeExtension.TextFontSize;
protected override void SetValue(float value)
{
Component.fontSize = (int)value;
#if UNITY_EDITOR
// 确保编辑器预览刷新
if (!Application.isPlaying)
{
UnityEditor.EditorUtility.SetDirty(Component);
}
#endif
}
}
3.如有需要在编辑器下使用,则还需要编写对应的编辑器代码:
[TweenerEditor(TweenTypeExtension.TextFontSize)]
public class TweenTextEditor : TweenFloatBaseEditor
{
public override int Type => TweenTypeExtension.TextFontSize;
public override int RequireCurveCount => 1;
public override bool AllowQuickOperation => true;
public new TweenTextFontSize Tweener => Target as TweenTextFontSize;
}
该项目为自研自用插件,已经经过一定时间和多个中小型项目的积累验证,现决定开源供大家学习和使用,但并不意味着这是一个完成度很高的商业化插件,可能存在诸多功能缺失和隐性BUG,如无意外,该项目后续将不会再更新新功能,作者将着手开发一个全新的动画插件,将与当前版本并不兼容,新项目将在保持现有特性的前提下进行大规模重构,并着重于提高易用性、扩展性和性能。尽管如此,如果你在使用 UTween
的过程中遇到任何问题或者发现BUG,都可以在这个仓库的 Issues
中进行提交反馈,也欢迎想要共同改进完善插件的人发起 Pull Request
。