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

Unity调整分辨率后缩放画布,UI物体拖拽位置偏移问题求助

问题描述

为提升Android平台性能,我使用以下代码将屏幕分辨率调整为当前分辨率的一半:

Screen.SetResolution(Screen.currentResolution.width / 2, Screen.currentResolution.height / 2, true);

但画布仍保持1920x1080分辨率,因此需要对其进行缩放。然而缩放画布后,OnDrag中的拖拽操作无法正常工作,物体位置出现偏移。

若将画布的UI Scale Mode设置为Constant Pixel Size,拖拽无问题,但画布仍维持1920x1080分辨率;若选择Scale With Screen Size并设置Match:0.5,物体拖拽位置与预期不符,且游戏启动时物体位置异常。

我的拖拽代码如下:

public void OnDrag(PointerEventData eventData)
{
    rectTransform.SetAsLastSibling();
    rectTransform.anchoredPosition += eventData.delta;
}
public void OnEndDrag(PointerEventData eventData)
{
    pointerEventData = new PointerEventData(eventSystem);
    pointerEventData.position = Input.mousePosition;
}

(问题截图:Unity拖拽位置偏移问题)

解决方案

1. 让画布自动适配修改后的屏幕分辨率

别手动缩放画布,先确保画布能自动跟着屏幕分辨率走:

  • 把画布的Render Mode设为Screen Space - Overlay(最省心的模式)
  • 在设置分辨率的代码后,强制画布刷新,触发自适应逻辑

修改后的分辨率设置代码:

void Start()
{
    var targetWidth = Screen.currentResolution.width / 2;
    var targetHeight = Screen.currentResolution.height / 2;
    Screen.SetResolution(targetWidth, targetHeight, true);
    Canvas.ForceUpdateCanvases(); // 强制画布刷新,适配新分辨率
}

2. 修正拖拽逻辑,适配UI缩放比例

用Scale With Screen Size时,eventData.delta是屏幕像素单位,而anchoredPosition是画布的UI单位,必须做比例转换:

  • 先获取父级画布的CanvasScaler组件
  • 把拖拽的像素偏移除以画布的缩放因子,再赋值给anchoredPosition

修改后的拖拽代码:

private CanvasScaler _canvasScaler;

void Awake()
{
    _canvasScaler = GetComponentInParent<CanvasScaler>();
}

public void OnDrag(PointerEventData eventData)
{
    rectTransform.SetAsLastSibling();
    // 转换拖拽偏移量到UI坐标空间
    var scale = _canvasScaler.scaleFactor;
    rectTransform.anchoredPosition += eventData.delta / scale;
}

public void OnEndDrag(PointerEventData eventData)
{
    // 这里的代码完全没必要,直接删掉就行,OnEndDrag不需要重新创建PointerEventData
}

3. 正确配置CanvasScaler参数

如果用Scale With Screen Size模式,参数得配对:

  • Reference Resolution设为你原本的1920x1080
  • Match值根据需求调:0是优先匹配宽度,1是优先匹配高度,0.5是均衡适配
  • 拖拽元素的锚点(Anchor)设为中心,避免启动时位置异常

4. 应急方案:手动缩放画布(不推荐)

如果上面的方法都不生效,可以直接改画布的缩放值,但同样要处理拖拽的比例转换:

// 设置分辨率后手动缩放画布
var canvas = FindObjectOfType<Canvas>();
canvas.transform.localScale = new Vector3(0.5f, 0.5f, 1f);

这种情况下,拖拽代码还是要按方法2的逻辑,把eventData.delta除以0.5(也就是乘以2)再应用到anchoredPosition上。


内容的提问来源于stack exchange,提问作者DCYılmaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:23:09