如何处理不同的屏幕分辨率

71

我正在使用Unity 4.3.3制作游戏,针对的是Android和iOS设备。但由于我对Unity不太熟悉,不知道如何适配不同屏幕分辨率。

我想让游戏全屏运行。已在iPad 2上进行了测试,效果很好。但在iPhone 4上两侧被裁剪,在iPhone 5上则更严重。有什么解决方案吗?在Player Settings > iOS > OtherSettings > Target Resolution下应该选择哪个选项?


22
为什么会有负票?我一无所知只是想问个问题,这有什么问题吗? - Ashish Beuwria
我发现了这段视频。这是正确的方法吗? - Ashish Beuwria
我将它设为了null。你要找什么?GUI组件?HUD? - Nick
@Nick 我只想在不同的分辨率下以全屏模式运行我的游戏。我已经编辑了我的问题。 - Ashish Beuwria
也许这个线程能够帮到你:更改分辨率 - AlexAlmenara
11个回答

47

Unity会根据屏幕的宽高比来调整游戏内相机的尺寸。显然,这并不总是需要的,因此有一些绕过这个问题的方法:

1)第一种方法非常容易实现,但通常效果不佳。您可以简单地更改相机的宽高比以匹配您设计游戏时使用的宽高比。例如,如果您的游戏设计为4:3,则可以执行以下操作:

Camera.aspect = 4f/3f;

请记住,这将会导致游戏在不同的宽高比下变形。

2) 另一种方法稍微复杂一些,但结果会更好。如果您正在使用正交相机,请牢记一件重要的事情,无论使用什么屏幕分辨率,正交相机都会保持高度不变,只更改宽度。例如,使用大小为 10 的正交相机,高度将被设置为 2。基于此,您需要补偿每个级别中最宽的可能相机(例如,具有更宽的背景)或动态更改相机的正交大小,直到其宽度与您创建的相匹配。

GUI 组件更容易实现,只需按需要将其位置设置为依赖于屏幕分辨率即可。例如,如果您希望按钮出现在右上角,则仅需将其位置设置为position = new Vector2(Screen.width - 50, 50);

编辑:由于您提到了使用的设备,我查找了一些信息以查找每个设备使用的宽高比:iPad2=4:3,iPhone4=3:2,iPhone5=16:9

既然您说在 iPad2 上看起来完美,我猜测您已经设计了一个使用 4:3 宽高比的游戏,因此您提到的“剪切”只是您的正交相机已经变宽了。解决方案是使用我上述的两种方法之一。

您可以在 Unity 编辑器中很容易地看到它在每个设备上的外观。如果您转到游戏标签(按下 Unity 编辑器中的播放时弹出的选项卡),您将看到它具有设备名称、分辨率和宽高比。更改这将使您看到不同宽高比下的外观。


感谢Steven提供这么详细的答案,但我想在所有设备上以全屏模式运行我的游戏。我已经编辑了我的问题以表达我确切的需求。我该怎么做? - Ashish Beuwria
@AshishBeuwria 我已经编辑了我的答案,以反映您提供的新信息。我提到的两个解决方案似乎仍然是您需要解决问题的方法。您在iPhone屏幕两侧看到的黑色条纹只是因为您的屏幕更宽,因此游戏内摄像机也更宽。 - Steven Mills
但我使用的是透视相机而不是正交相机。 - Ashish Beuwria

4
如果您的目标是获取先前的宽度:
[RequireComponent(typeof(Camera))]
public class ResizeCamera : MonoBehaviour 
{
    private float   DesignOrthographicSize;
    private float   DesignAspect;
    private float   DesignWidth;

    public  float   DesignAspectHeight;
    public  float   DesignAspectWidth;

    public void Awake()
    {
        this.DesignOrthographicSize = this.camera.orthographicSize;
        this.DesignAspect = this.DesignAspectHeight / this.DesignAspectWidth;
        this.DesignWidth = this.DesignOrthographicSize * this.DesignAspect;

        this.Resize();
    }

    public void Resize()
    {       
        float wantedSize = this.DesignWidth / this.camera.aspect;
        this.camera.orthographicSize = Mathf.Max(wantedSize, 
            this.DesignOrthographicSize);
    }
}

4
您可以尝试使用Camera.ScreenWidth和Camera.ScreenHeight来捕获设备分辨率。然后进行一些数学计算,计算出与您拥有的分辨率的差异,并将其应用于父对象。这将使所有内容都按比例缩放以适应设备分辨率,而不需要为不同分辨率的设备使用多个图像分辨率等。

3
你需要根据设备的宽高比来更改相机视口。 假设你为720x1080制作了游戏,则在脚本中应这样做:
float xFactor = Screen.width / 720f;
float yFactor = Screen.height  / 1080f;

Camera.main.rect = new Rect(0,0,1,xFactor/yFactor);

或者

另一种方法是,如果您正在为纵横比为9:16的游戏进行开发,则可以在脚本中执行以下操作:

public float targetRatio = 9f/16f; //The aspect ratio of your game
void Start()
{
    Camera cam = GetComponent<Camera>();
    cam.aspect = targetRatio;
}

2
好的,这是一个很大的问题。许多人已经提到了强制使用特定的屏幕比例,这是一个值得考虑的好解决方案。但对于许多游戏来说,并不是适当的解决方案。对于许多游戏设计来说,你希望游戏感觉像是原生运行在设备/屏幕上,并且你需要尽可能地利用每一个屏幕的空间。为了做到这一点,你必须为游戏中的每个系统在不同大小和形状的屏幕上进行构建和测试。这是与构建应用程序和网站以适配多种设备类似的问题。

屏幕尺寸

可以使用DPI分辨率来通过编程的方式检索屏幕尺寸,例如:

Resolution res = Screen.currentResolution;
float screenSquareInches = res.width * res.height / Screen.dpi;

对于通过相机查看的屏幕内容,只有一个变量需要缩放,那就是相机的大小(或者说游戏世界中需要挤压到屏幕上的物品数量)。你可以通过视野(用于3D游戏)或正交大小(用于2D游戏)来控制相机的大小。只有测试才能确定哪种方程式适用于最广泛的屏幕尺寸范围,但以下类似的方程式可能会很好地发挥作用:
// this should be a tweakable number, so you can fine tune it to your needs. It represents the screen size at which the camera size should not be scaled at all
float expectedScreenArea = 20;
// this number should also be tweakable, which declares how much smaller/larger text can get depending on the screen size. Generally larger screens are viewed from farther away, so scaling should be slight
float cameraScalingRate = 0.25f;
// multiply this number by the default/base camera size you have picked, whether that's field of view or orthographic size
float cameraSizeMultiplier = 1 + (screenSquareInches / expectedScreenArea - 1) * cameraScalingRate;

好的,这将帮助您在缩放游戏世界方面做得很好,但是UI元素呢?比如文本、HUD和屏幕控件等。对于像文本这样的元素,上述公式应该可以很好地工作,尽管您可能需要不同的缩放率。对于屏幕控件,您可能需要更全面的转换,例如在平板电脑上将摇杆移动到屏幕底部角落而不是侧面居中,或者如果它不是触摸屏设备,则完全删除屏幕上的控件。这超出了本问题的范围。

屏幕纵横比

屏幕的纵横比(宽度与高度之比)也很重要,需要单独处理。通常最好的方法是冻结屏幕的垂直高度,因此随着屏幕变得更宽,屏幕上的元素不会被缩放,但随着屏幕变得更高,屏幕上的元素按比例缩放,以适应屏幕增长的高度。对于相机来说,这已经是默认行为,但对于UI元素,您必须设置它。如果您正在使用具有画布的新UI系统,则相对容易。在CanvasScalar组件上,有一个属性,控制元素如何根据纵横比进行缩放。将其更改为匹配宽度或高度,并将其匹配为高度。

进一步考虑

支持不同的屏幕尺寸和形状需要考虑的不仅是使所有内容适合屏幕。您还需要确保游戏在不同屏幕上运行良好。这范围从微妙之处,例如不要让玩家在小屏幕上感到幽闭恐惧,到确保敌人不能在屏幕外向玩家开火,以确保更新边界以使元素保持在屏幕上。 如果这是一款PC游戏,还需要考虑到某些人可能会将计算机插入不同的屏幕或随时更改分辨率。考虑到这一点,有必要根据需要重新运行上述方程式,以便玩家无需退出游戏即可正确对齐事物。


2

我知道这是一个老帖子,但人们可能仍然在寻找答案。

要将透视相机调整到具有不同行为的不同屏幕宽高比,需要一些三角学知识。关于这方面的所有必要信息都在这里:https://en.wikipedia.org/wiki/Angle_of_view

如果你想要一个简单的解决方案,这里有一个适用于所有相机类型的解决方案:http://u3d.as/oUX


1
我解决这个问题最简单的方法就是像Steven指出的那样,强制我的透视相机纵横比与我开发的一致。当然,如果我为设备开发的纵横比与设备本身不同,这会使一些对象变形。对于UI对象,如果您正在使用内置功能,则可以根据屏幕尺寸的百分比创建矩形。
Rect(0.5 * Screen.width, 0.5 * Screen.height, 0.25 * Screen.width, 0.25 * Screen.height) 

那将把左上角放在屏幕中心,并创建一个矩形,其高度和宽度均为屏幕的1/4。我正在使用NGUI 2.7进行UI设计,到目前为止还没有发现不同纵横比的问题,该软件使用正交相机来渲染UI。

更好的制作动态GUI的方法,我认为应该只在onStart()方法中计算大小和位置,除非你想支持横向和纵向两种模式,那么就在LateUpdate方法中检查Screen.orientation,因为在onGUI方法中计算Rect或进行不必要的检查是不高效的。 - Zeeshan Anjum

0
如果您正在开发2D游戏,即相机处于正交视图,则只需执行以下代码并将其附加到游戏对象即可。它将根据屏幕分辨率缩放游戏对象(在本例中为精灵)。
void Resize()
{
    SpriteRenderer sr=GetComponent<SpriteRenderer>();
    if(sr==null) return;

    transform.localScale=new Vector3(1,1,1);

    float width=sr.sprite.bounds.size.x;
    float height=sr.sprite.bounds.size.y;


    float worldScreenHeight=Camera.main.orthographicSize*2f;
    float worldScreenWidth=worldScreenHeight/Screen.height*Screen.width;

    Vector3 xWidth = transform.localScale;
    xWidth.x=worldScreenWidth / width;
    transform.localScale=xWidth;

    Vector3 yHeight = transform.localScale;
    yHeight.y=worldScreenHeight / height;
    transform.localScale=yHeight;

}

0

现在对于Unity来说非常容易,因为Unity3D有自己的UI系统。对于3D Unity调整摄像机随着屏幕大小自动调整。 实际上UI会出现问题,而且有一点棘手。首先要找出哪些元素需要根据屏幕大小改变位置和大小。 例如,如果您在屏幕中心正好有一个按钮。那么它不需要根据屏幕改变位置。它将保持在中心。

现在让我们以一种场景为例,在这种场景中,您在屏幕角落里有一个按钮,就像我们在右上方或左上方看到的暂停按钮。现在您必须相应地将按钮锚定在角落。无论游戏在哪个屏幕大小下运行,暂停按钮都应该固定在角落。

现在让我们再看另一种情况,您的菜单中有一个背景。现在您将要为此BG精灵应用拉伸。这个背景将会根据需要进行拉伸和缩小,但其上所有项目的大小都是固定的。 为此,建议使用平面的BG,以便16:10或4:3的同一BG可以具有良好的质量 (这全部都是关于Unity原生UI的)


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接