You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用DOTween实现拖动UI时的补间动画 仅Y轴跟随手指移动问题排查

问题排查
  • 触发时机错误:GestureState.Up通常对应手势抬起的状态,拖动跟随逻辑应该放在手势移动中的状态回调(如GestureState.Move)下
  • 缓动冲突:每次触发都调用带0.5s时长的DOMove方法,上一次未完成的缓动会和新缓动冲突,导致跟随延迟、错位
  • 坐标系不匹配:_MousePos是屏幕像素坐标,不能直接赋值给Transform的位置坐标(UGUI为锚点局部坐标,2D Sprite为世界坐标),直接赋值会出现大幅位置偏差
  • X轴赋值错误:代码写死目标X坐标为0,没有保留图片原本的X轴坐标,不符合X轴固定的需求
修正代码

适用UGUI图片场景(绝大多数拖动图片需求为此场景)

public void CallEvent() 
{
    // 替换为你手势SDK对应的移动中状态枚举值
    case GestureState.Move:
        if(this.gameObject.name == "Cover") 
        {
            RectTransform rect = GetComponent<RectTransform>();
            RectTransform parentRect = transform.parent.GetComponent<RectTransform>();
            // 屏幕坐标转父容器局部坐标,Canvas为Screen Space-Overlay模式时相机传null
            if (RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRect, _MousePos, null, out Vector2 localPos))
            {
                // 直接赋值坐标实现无延迟跟随,保留原X轴
                rect.anchoredPosition = new Vector2(rect.anchoredPosition.x, localPos.y);
                
                // 若需使用DOTween实现小幅缓动效果,用以下代码替换上面的直接赋值即可
                // rect.DOKill();
                // rect.DOAnchorPosY(localPos.y, 0.05f);
            }
        }
        break;
}

适用世界空间2D Sprite场景

public void CallEvent() 
{
    case GestureState.Move:
        if(this.gameObject.name == "Cover") 
        {
            Vector3 worldPos = Camera.main.ScreenToWorldPoint(_MousePos);
            transform.position = new Vector3(transform.position.x, worldPos.y, transform.position.z);
        }
        break;
}
注意事项
  • 若你的Canvas为Screen Space-Camera模式,RectTransformUtility.ScreenPointToLocalPointInRectangle的第三个参数需要传入Canvas绑定的渲染相机,不能传null
  • 若使用DOTween缓动,必须在每次调用缓动前调用DOKill()杀掉未完成的旧缓动,避免缓动堆积导致错位

内容的提问来源于stack exchange,提问作者heinzQ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:54:01