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

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

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

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

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

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

  • 配置与回调:

    • timeScale、isBackwards、id、target:基础播放配置及绑定的目标(如 Transform)。

    • onPlay、onUpdate、onComplete、onKill 等:各种生命周期回调函数。

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

    • typeofT1、typeofT2、typeofTPlugOptions:用于记录泛型 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 回调,清除 target 和 id 引用。

  • 消除 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,返回 true。TweenManager 收到 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 的开销。

相关推荐
淡海水1 小时前
07-02-源码-.NET Core GC分配路径
算法·unity·c#·.netcore·gc·1024程序员节
FFFFujige4 小时前
【Unity】基于Dots + Luban的Buff模块
unity·游戏引擎
紫龙大侠4 小时前
Unity许可证文件(激活成功后)默认保存位置
unity
Msir_Modern8 小时前
Noita 元胞沙盒笔记
算法·unity·c#·游戏引擎·元胞自动机
天天进步201512 小时前
Unity 2020.3 反复提示安全模式:一次 CS0009 与 DLL 文件占用的排查记录
unity·1024程序员节
淡海水14 小时前
07-04-源码-.NET Core GC清扫与压缩
unity·架构·c#·.netcore·gc·1024程序员节
小贺儿开发1 天前
《长征 · 征途》Unity 三维互动沙盘
科技·3d·unity·1024程序员节·地形·互动·沙盘
上班摸鱼下班游戏1 天前
Unity 仿生智能算法 从蚁群算法 开始
算法·unity·游戏引擎
Wanda12141 天前
机器人与机电一体化3D数字孪生机器-Day6
unity·机器人·数字孪生·1024程序员节
淡海水2 天前
07-03-源码-.NET Core GC标记与扫描
unity·c#·.netcore·gc