基类 DG.Tweening.Tween的源码解读

这份代码是 DOTween 引擎中最基础、最核心的抽象基类 DG.Tweening.Tween 的完整定义。

无论是单体动画 Tweener(如 DOMove)还是组合序列 Sequence,都继承自这个类。它负责定义动画的所有基本状态、回调函数、类型元数据,并实现了驱动动画生命周期的最核心方法 DoGoto

核心结构与关键细节拆解:

1. 字段定义(成员变量)

代码中的字段可以分为四大核心类别:

  • 配置与回调

    • timeScaleisBackwardsidtarget:基础播放配置及绑定的目标(如 Transform)。

    • onPlayonUpdateonCompleteonKill 等:各种生命周期回调函数。

  • 对象池类型匹配元数据(与 TweenManager 联动)

    • typeofT1typeofT2typeofTPlugOptions:用于记录泛型 Tweener 的实际类型(如 Vector3, Vector3, VectorOptions)。上一问提到的 TweenManager 倒序扫描池子时,比对的就是这三个字段。
  • 运行时状态标记

    • active:标识当前 Tween 是否处于活跃状态(未被销毁)。

    • activeId:在 TweenManager._activeTweens 数组中的物理索引。

    • startupDone:是否已完成首次初始化(捕获起始值/目标值)。

    • playedOnce:是否已经播放过至少一次(用于控制 onStart 回调只触发一次)。

  • 时间与进度控制

    • duration(单次循环时长)、fullDuration(包含 loops 的总时长)、position(当前单次循环中的位置)、completedLoops(已完成的循环次数)。

2. 对象池复用机制:Reset() 方法

当动画播放结束并被 TweenManager 放入对象池(Despawn)时,会调用此方法:

  • 重置所有参数 :将 timeScale 重置为 1f,置空所有 onStart/onComplete 回调,清除 targetid 引用。

  • 消除 GC 分配 :清空引用避免内存泄漏,同时将数值重置,使当前对象恢复为"干净"的状态,以便下次直接取出使用,实现零 GC 循环利用

3. 最核心的心脏逻辑:DoGoto() 静态方法

DoGoto 是 DOTween 驱动动画数值更新、计算缓动、触发回调的核心算法管线。TweenManager 在每一帧更新时都会调用此方法。

执行流程拆解:

  1. 懒加载初始化(Startup)

    复制代码
    if (!t.startupDone && !t.Startup()) return true;

    如果 Tween 是第一次运行,在此处触发 Startup(),延迟捕获 Transform 的当前起始位置(Start Value)。

  2. 首次播放回调(onStart / onPlay

    复制代码
    if (!t.playedOnce && updateMode == UpdateMode.Update) {
        t.playedOnce = true;
        if (t.onStart != null) Tween.OnTweenCallback(t.onStart);
        if (t.onPlay != null) Tween.OnTweenCallback(t.onPlay);
    }
  3. 循环与完成状态判定

    • 计算本次更新跨过了多少次循环 (num2),用于精准触发 onStepComplete

    • 判断当前进度是否达到了 loops 上限,更新 t.isComplete 状态。

  4. 计算 Yoyo 反弹模式

    复制代码
    bool useInversePosition = t.loopType == LoopType.Yoyo && ((t.position < t.duration) ? (t.completedLoops % 2 != 0) : (t.completedLoops % 2 == 0));

    如果是 Yoyo(往复)模式,根据当前完成的循环次数是奇数还是偶数,计算出当前帧到底应当正向插值还是反向插值。

  5. 应用实际动画数值 (ApplyTween)

    复制代码
    if (t.ApplyTween(prevPosition, num, num2, useInversePosition, updateMode, updateNotice)) return true;

    这是一个多态抽象方法。具体的子类(如 TweenerCore)在此方法中计算 Ease 曲线并赋值给物体的属性 (例如改变 transform.position)。

  6. 按顺序触发生命周期回调

    顺序为:onUpdate,``onRewind, onStepComplete(单步循环完成, onComplete(全部完成) ,onPause

  7. AutoKill 返回判定

    复制代码
    if (t.autoKill) return t.isComplete;

    如果动画已播放完成且开启了 autoKill,返回 trueTweenManager 收到 true 后就会将此 Tween 加入回收队列(_KillList)。

4. 安全回调机制:OnTweenCallback()

用于执行用户传入的委托回调(如 .OnComplete(...)):

复制代码
if (DOTween.useSafeMode) {
    try { callback(); }
    catch (Exception ex) { Debugger.LogWarning(...); return false; }
} else {
    callback();
}
  • 安全模式(Safe Mode) :如果开启,用户回调函数报错(如空指针异常)时会被 try-catch 捕获并记录日志,防止用户的业务逻辑报错导致整个 DOTween 更新管线崩溃或游戏主循环卡死

  • 性能模式 :关闭 Safe Mode 时直接调用,节省 try-catch 的开销。

相关推荐
Behaviour2 小时前
Unity游戏之Jenkins的安装部署应用
游戏·unity·jenkins
大Mod_abfun4 小时前
Unity案例10-水晶矿石碰撞碎裂案例
unity·游戏引擎
xcLeigh5 小时前
Unity基础:Input输入系统入门——键盘、鼠标与触摸检测
unity·计算机外设·游戏引擎
zhchyun20081 天前
【Unity UI 进阶】仿 Element UI 打造企业级 Unity UI 组件库(05)
ui·unity·游戏引擎
_ZHOURUI_H_1 天前
不做完整 ECS,只优化数据布局:Unity EasyECS 到底是什么
unity·性能优化·游戏引擎
郝学胜-神的一滴2 天前
Horse3D 游戏引擎研发笔记(七):Clydesdale——从流式日志到多输出订阅
c++·qt·unity·游戏引擎·图形渲染·unreal engine·opengl
小贺儿开发3 天前
Unity 程序员编曲花絮:汪峰《河流》细节修复
科技·学习·unity·程序员·音乐·demo·写代码
598866753@qq.com3 天前
Unity UniText笔记
unity·unitext