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

Unity2D 2021.3.15f1:如何适配分辨率拉伸GameObject并实现屏幕边缘碰撞检测?

2D游戏分辨率适配与屏幕边缘碰撞解决方案

一、GameObject自适应分辨率拉伸

无需绑定固定16:9比例,直接基于相机视口动态计算缩放值,适配任意屏幕尺寸:

1. 初始化缩放计算(正交相机)

在GameObject的脚本中,通过相机正交尺寸和宽高比,算出适配当前屏幕的缩放比例:

void Start()
{
    Camera mainCam = Camera.main;
    // 获取相机覆盖的世界空间高度、宽度
    float worldHeight = mainCam.orthographicSize * 2f;
    float worldWidth = worldHeight * mainCam.aspect;

    // 替换为你设计时的参考宽度(比如16:9下GameObject的宽度)
    float referenceWidth = 10f;
    float scaleFactor = worldWidth / referenceWidth;

    // 应用缩放,保持宽高比一致
    transform.localScale = new Vector3(scaleFactor, scaleFactor, 1f);
}

2. 监听屏幕尺寸变化,实时更新缩放

添加屏幕尺寸变化监听,确保窗口或设备分辨率改变时,GameObject自动适配:

void OnEnable()
{
    Screen.onSizeChanged += UpdateObjectScale;
}

void OnDisable()
{
    Screen.onSizeChanged -= UpdateObjectScale;
}

void UpdateObjectScale(int width, int height)
{
    Camera mainCam = Camera.main;
    float worldHeight = mainCam.orthographicSize * 2f;
    float worldWidth = worldHeight * mainCam.aspect;
    float referenceWidth = 10f;
    float scaleFactor = worldWidth / referenceWidth;
    transform.localScale = new Vector3(scaleFactor, scaleFactor, 1f);
}

二、屏幕边缘碰撞检测与反弹

放弃相机外的灰色矩形碰撞体,直接通过世界坐标计算屏幕边缘,高效实现碰撞检测和反弹:

1. 计算屏幕边缘的世界坐标

根据相机类型(正交/透视),获取屏幕四个边缘对应的世界位置:

// 正交相机用此方法
private Vector2 GetOrthographicScreenEdges()
{
    Camera mainCam = Camera.main;
    float halfHeight = mainCam.orthographicSize;
    float halfWidth = halfHeight * mainCam.aspect;
    return new Vector2(halfWidth, halfHeight);
}

// 透视相机用此方法
private Vector2 GetPerspectiveScreenEdges()
{
    Camera mainCam = Camera.main;
    Vector3 bottomRightWorld = mainCam.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, mainCam.nearClipPlane));
    return new Vector2(Mathf.Abs(bottomRightWorld.x), Mathf.Abs(bottomRightWorld.y));
}

2. 碰撞检测与反弹逻辑

在FixedUpdate中检测GameObject位置是否超出边缘,触发反弹和自定义碰撞事件:

public float moveSpeed = 5f;
private Vector2 moveDirection = new Vector2(1, 1);

void FixedUpdate()
{
    // 根据相机类型选择对应的边缘计算方法
    Vector2 screenEdges = GetOrthographicScreenEdges();
    Vector2 currentPos = transform.position;

    // 左右边缘碰撞检测与反弹
    if (currentPos.x > screenEdges.x || currentPos.x < -screenEdges.x)
    {
        moveDirection.x *= -1;
        OnEdgeCollision(ScreenEdgeType.LeftRight);
        // 修正位置,避免物体卡在边缘外
        currentPos.x = Mathf.Clamp(currentPos.x, -screenEdges.x, screenEdges.x);
        transform.position = currentPos;
    }

    // 上下边缘碰撞检测与反弹
    if (currentPos.y > screenEdges.y || currentPos.y < -screenEdges.y)
    {
        moveDirection.y *= -1;
        OnEdgeCollision(ScreenEdgeType.TopBottom);
        currentPos.y = Mathf.Clamp(currentPos.y, -screenEdges.y, screenEdges.y);
        transform.position = currentPos;
    }

    // 应用移动
    transform.Translate(moveDirection * moveSpeed * Time.fixedDeltaTime);
}

// 自定义碰撞事件处理
void OnEdgeCollision(ScreenEdgeType edgeType)
{
    // 这里添加你的业务逻辑,比如播放音效、更新分数等
    Debug.Log($"碰撞到屏幕边缘: {edgeType}");
}

// 边缘类型枚举
enum ScreenEdgeType
{
    LeftRight,
    TopBottom
}

3. 注意事项

  • 若GameObject带有Collider2D,无需额外添加边缘碰撞体,直接用坐标计算更高效
  • 透视相机的边缘计算需注意近裁剪面设置,避免坐标偏差

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:50:15