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

Unity移动端不同分辨率下画面两侧裁剪(非Canvas相关)修复方法

Unity 3D竖屏游戏多分辨率适配修复方案

问题根因

该问题和Canvas设置无关,核心是相机视锥体宽高比未做多分辨率适配:
开发阶段使用的1080×1920为标准9:16比例,而部署的1080×2340设备为9:19.5的窄长屏比例。如果相机视口默认锁定纵向可视范围,横向可视范围会随宽高比变小被压缩,直接导致开发阶段可见的两侧内容被裁剪;硬编码的屏幕移动边界不会随分辨率变化更新,就会出现玩家能移动到可视区域外的问题。

分步修复操作

1. 挂载相机适配脚本,从根源解决内容裁剪

根据你使用的相机类型,把对应脚本挂到主相机上,以开发分辨率为基准动态调整视口范围,优先保证横向内容完整不裁剪,纵向多出的区域做自然延伸:

正交相机适配(固定视角3D/2.5D游戏通用)

using UnityEngine;
[ExecuteAlways]
public class CameraAspectFitter : MonoBehaviour
{
    // 开发阶段基准分辨率
    private const float DesignWidth = 1080f;
    private const float DesignHeight = 1920f;
    // 填你开发阶段调试好的正交相机Size值
    public float baseOrthoSize = 5f;
    private Camera _mainCam;
    private int _lastScreenWidth, _lastScreenHeight;

    private void Awake()
    {
        _mainCam = GetComponent<Camera>();
        FitCameraViewport();
    }

    private void Update()
    {
        // 分辨率变化时自动重适配(适配折叠屏、窗口大小调整场景)
        if (_lastScreenWidth != Screen.width || _lastScreenHeight != Screen.height)
        {
            FitCameraViewport();
        }
    }

    private void FitCameraViewport()
    {
        _lastScreenWidth = Screen.width;
        _lastScreenHeight = Screen.height;
        float designAspect = DesignWidth / DesignHeight;
        float currentAspect = (float)Screen.width / Screen.height;
        
        // 窄长屏放大正交Size,保证横向内容不被裁剪
        if (currentAspect < designAspect)
        {
            _mainCam.orthographicSize = baseOrthoSize * (designAspect / currentAspect);
        }
        else
        {
            // 宽屏保持基准Size,两侧内容自然延伸
            _mainCam.orthographicSize = baseOrthoSize;
        }
    }

    /// <summary>
    /// 获取当前分辨率下相机在指定平面的可视边界,用于玩家移动限制
    /// </summary>
    public Bounds GetVisibleWorldBounds(float targetPlaneZ = 0f)
    {
        float camDistance = Mathf.Abs(targetPlaneZ - transform.position.z);
        Vector3 minPoint = _mainCam.ScreenToWorldPoint(new Vector3(0, 0, camDistance));
        Vector3 maxPoint = _mainCam.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, camDistance));
        Bounds visibleBounds = new Bounds();
        visibleBounds.SetMinMax(minPoint, maxPoint);
        return visibleBounds;
    }
}

透视相机适配

如果使用透视相机,把上述脚本中修改orthographicSize的逻辑替换为修改fieldOfView即可,baseOrthoSize字段替换为你开发阶段调好的基准FOV值,适配逻辑完全一致。

2. 动态计算玩家移动边界,禁止硬编码

删除玩家控制脚本中写死的屏幕边界坐标,每次玩家移动前调用上述脚本的GetVisibleWorldBounds方法,获取当前分辨率下的真实可视边界,用数值钳制方法限制玩家移动范围:

// 玩家移动脚本中的边界限制示例
public class PlayerMovement : MonoBehaviour
{
    [SerializeField] private CameraAspectFitter mainCamFitter;
    [SerializeField] private float moveSpeed = 5f;
    private Bounds _visibleBounds;

    private void Start()
    {
        _visibleBounds = mainCamFitter.GetVisibleWorldBounds(transform.position.z);
    }

    private void Update()
    {
        // 读取移动输入
        float moveX = Input.GetAxis("Horizontal");
        float moveY = Input.GetAxis("Vertical");
        Vector3 targetPos = transform.position + new Vector3(moveX, moveY, 0) * moveSpeed * Time.deltaTime;
        // 限制玩家在可视范围内
        targetPos.x = Mathf.Clamp(targetPos.x, _visibleBounds.min.x, _visibleBounds.max.x);
        targetPos.y = Mathf.Clamp(targetPos.y, _visibleBounds.min.y, _visibleBounds.max.y);
        transform.position = targetPos;
    }
}

3. 长屏场景兜底适配

窄长屏设备上下会比基准分辨率多出一部分可视区域,做两个简单调整避免穿帮:

  • 把场景地面、远景背景板的纵向长度拉长25%~30%,覆盖当前市面上最长的9:21比例竖屏设备
  • 关键关卡触发点、可收集道具不要贴场景上下边缘摆放,避免短屏设备上元素超出可视范围

注意事项

  • 不要在Player Settings中开启固定分辨率缩放,不要手动修改相机的Viewport Rect参数,避免覆盖脚本适配逻辑
  • 编辑器下可直接切换Game视图分辨率,测试1080×1920、1080×2340、720×1280等主流竖屏分辨率,确认两侧无裁剪、玩家不会跑出可视区即可打包测试

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:54:18