运行环境:Unity 2018.4.0f1、DOTween v1.2.280、DOTweenPro v1.0.155

原因:
    UGUI上的元素,都采用 RectTransform 组件进行变换。在Inspector上显示的坐标都是 anchoredPosition,而非 localPosition。anchoredPosition 和 localPosition 不是任何时候都相等的,不能直接以此数值做 DOLocalMove 动画。

需要明确:
    anchoredPosition 为: “子物体pivot” 相对于 “子物体锚点” 的位移。
    localPosition 为:“子物体pivot” 相对于 “父物体pivot ” 的位移。

即,如果 “子物体锚点” 没有与 “父物体pivot ” 重合,那 localPosition 就与 anchoredPosition 不等,就可能出现问题。

使用实际的 localPosition 做 DOLocalMove 动画,可以 “一定程度上” 解决问题。

查看 localPosition 的方法如下图:

unity 重新播放动画 unity动画播放位置无法改变_UGUI

为什么只是“一定程度上” 解决问题?
因为还需要特别注意的 两个问题。

1、经过测试如果 DOToweenAnimation组件 上的移动方式为 “TO” 时,总能得到正确的结果;而如果移动方式为 “From” 则不行。这应该是Dotween本身的一个Bug,等待后续在新版本中验证是否会修复。

2、设备的分辨率变化 可能使物体的 localPosition 发生变化(“设备分辨率” =》 “锚点四散的物体的大小” =》 “其子物体的 localPosition”),也就是说,就算你的动画在设计分辨率下运行完美,也可能会在与设计分辨率比例不同的机器上运行出错。
避免此问题的办法是:让物体的 localPosition 保持稳定。即,让其父物体的的大小不随意变化(必要的时候可以考虑增加一些中间层级!)。

---------------------------------------------------- NRatel割 ----------------------------------------------------

想要彻底解决问题,需要直接使用 DOAnchorPos() / DOAnchorPos3D() 。

这样,
在使用时可以直接使用 Inspector 上显示的坐标。
还不用考虑设备分辨率变化对动画的影响(物体的 anchoredPosition 不受其父物体大小的影响)。

其实,在UGUI上,对位置的操作(尤其是动画)应尽量针对 anchoredPosition,而非 localPosition。

---------------------------------------------------- NRatel割 ----------------------------------------------------

代码中不用说,主要的问题是 DOTweenAnimation 组件本身并没有 AnchorPos/AnchorPos3D 的可选项。
好在源代码开放且简单,可以自行对其进行扩展。

需要增加代码的地方(这里只实现 AnchorPos3D

1、(DOTweenAnimation 中),增加动作类型。

unity 重新播放动画 unity动画播放位置无法改变_UGUI_02

2、(DOTweenAnimation 中),最终调用逻辑方法 DOAnchorPos3D。

unity 重新播放动画 unity动画播放位置无法改变_UGUI_03

3、(DOTweenAnimation 中),支持 DoRestart 时重新计算起始位置。

unity 重新播放动画 unity动画播放位置无法改变_预期不符_04

4、(DOTweenAnimationInspector 中),在 _AnimationTypeToComponent 字典中增加一行,用于约束 “动作类型 可作用于的 组件”。

unity 重新播放动画 unity动画播放位置无法改变_DOTween_05

5、(DOTweenAnimationInspector 中),增加动画类型字符串,用于在Inspector上展示,以及与 DOTweenAnimation组件中的  AnimationType 类型对应。

unity 重新播放动画 unity动画播放位置无法改变_UGUI_06

6、(DOTweenAnimationInspector 中),设置默认值。

unity 重新播放动画 unity动画播放位置无法改变_unity 重新播放动画_07

7、(DOTweenAnimationInspector 中),绘制一个Vector3用于填写坐标 、一个单选用于选择是否Snapping、一个单选用于选择是否 Relative。

unity 重新播放动画 unity动画播放位置无法改变_UGUI_08

 ---------------------------------------------------- NRatel割 ----------------------------------------------------

结果如下,运行与预期完全一致:

unity 重新播放动画 unity动画播放位置无法改变_UGUI DOTween 问题_09