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

如何让Unity WebGL游戏适配浏览器窗口?点击偏移问题求解

解决Unity WebGL缩放后交互错位的问题

这问题我之前帮朋友踩过坑——用CSS transform: scale()做视觉缩放确实会导致Unity交互错位,核心原因是Unity的输入系统是基于原始画布尺寸计算的,和你用CSS做的视觉缩放完全脱节,相当于画面被拉伸了,但碰撞检测、UI点击的坐标还是按原始1152×648来算的,自然点不准。

给你几个靠谱的解决方案,按优先级排序:

1. 用Unity内置的WebGL自适应缩放(最推荐,零额外代码)

Unity本身就提供了WebGL画布的自适应功能,完全不用自己写JS,还能保证输入和视觉同步:

  • 打开Unity编辑器,进入Edit > Project Settings > Player,切换到WebGL平台
  • 在Resolution and Presentation面板里:
    • 保持Default Canvas Width=1152,Default Canvas Height=648(满足大屏用户的高分辨率需求)
    • 勾选Resize Canvas,然后把Render Mode改成Scale to Fit(这个模式会保持游戏的原始宽高比,自动缩放适配窗口,不会拉伸变形;如果需要填充整个窗口可以选Scale to Fill,但会裁剪边缘)
    • 保持默认的WebGL Template即可,Unity会自动生成适配的JS代码,输入坐标会自动对应缩放后的视觉位置

用这个方案,大屏用户看到的是原始高分辨率,小屏用户会自动缩放适配,而且完全不会有交互错位的问题。

2. 手动修正Unity输入坐标(自定义JS场景下可用)

如果必须保留你自己写的JS缩放逻辑,那需要在Unity里修正输入坐标,让它和CSS缩放比例同步:

第一步:在JS里存储缩放比例

修改你的resizeGame函数,把当前的缩放比例存到全局变量:

function resizeGame() {
    var winSize = {w:1152, h:648};
    var fill1Div = document.getElementById('gameContainer');
    var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    var scaleWidth = width / winSize.w;
    var scaleHeight = height / winSize.h;
    var bgScale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight;
    bgScale = bgScale >= 1 ? 1 : bgScale;
    
    // 存储缩放比例到全局变量
    window.gameScale = bgScale;
    
    var bgTransformScale = "scale(" + bgScale + ")";
    fill1Div.style.transform = bgTransformScale;
    fill1Div.style.webkitTransform = bgTransformScale;
    fill1Div.style.MozTransform = bgTransformScale;
    fill1Div.style.msTransform = bgTransformScale;
    fill1Div.style.OTransform = bgTransformScale;
}
window.addEventListener("resize", resizeGame);
window.addEventListener("orientationchange", resizeGame);
resizeGame();

// 给Unity提供获取缩放比例的方法
function GetGameScale() {
    return window.gameScale || 1;
}

第二步:在Unity C#脚本里修正输入坐标

写一个脚本,从JS获取缩放比例,然后修正鼠标/触摸坐标:

using UnityEngine;

public class InputScaler : MonoBehaviour
{
    private float _scaleFactor = 1f;

    void Start()
    {
        // 初始化时获取缩放比例
        _scaleFactor = GetGameScale();
    }

    void Update()
    {
        // 实时更新缩放比例(窗口变化时同步)
        _scaleFactor = GetGameScale();
        
        // 修正鼠标坐标:把浏览器窗口坐标转换成游戏原始画布的坐标
        Vector2 scaledMousePos = new Vector2(
            Input.mousePosition.x / _scaleFactor,
            Input.mousePosition.y / _scaleFactor
        );
        
        // 之后所有交互逻辑都用scaledMousePos代替Input.mousePosition
        // 比如UI点击、射线检测等
        ExampleRaycast(scaledMousePos);
    }

    // 调用JS全局方法获取缩放比例
    [System.Runtime.InteropServices.DllImport("__Internal")]
    private static extern float GetGameScale();

    // 示例:用修正后的坐标做射线检测
    void ExampleRaycast(Vector2 mousePos)
    {
        Ray ray = Camera.main.ScreenPointToRay(mousePos);
        if (Physics.Raycast(ray, out RaycastHit hit))
        {
            // 处理点击逻辑
        }
    }
}

把这个脚本挂在你的主相机或者全局管理器上,所有依赖鼠标/触摸的交互都用修正后的坐标,就能解决错位问题。

3. 用CSS zoom属性代替transform(兼容性有限)

如果你只需要兼容Chrome/Edge这类浏览器,可以把transform: scale()换成zoom属性:

// 替换原来的transform相关代码
fill1Div.style.zoom = bgScale;

zoom是浏览器对整个元素的缩放,包括输入事件的坐标,所以不会出现错位。但注意Firefox对zoom的支持很差,所以这个方案只适合特定场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:36:59