在Unity中支持多种高宽比

我一直在试图创build一个支持Android和平板电脑的设备的每个纵横比的Unity 2D游戏。 有没有办法做到这一点,由Unity提供或推荐?

Solutions Collecting From Web of "在Unity中支持多种高宽比"

有几件事情应该考虑。 首先是什么元素应该允许规模? 有两个类别,即UI和游戏元素。

游戏元素部分可能意味着很多事情。 如果游戏空间有限,关键是典型的,包括“负面空间”的大部分,或图像中不影响游戏的部分显着。 例如,下面的图像可以从左侧和右侧裁剪,而不会显着影响图像。 把图像的中心部分作为关键要素,或者一边。

在这里输入图像说明

人们也可以拉伸元素,尽pipe这可能会导致不良的影响。 对于这样的背景元素来说,通过不同方面的口粮进行图像过滤和testing是最好的方法。 这些背景元素可以放置在背景中,canvas被设置为“按屏幕大小缩放”,并将“屏幕匹配模式”设置为最适合您的图像的效果。 有关更多信息,请参阅“ canvas缩放器 ”。

至于其他UI元素,关键是要使用锚点。 你可以告诉一个UI元素有多个像素,或者当你放置它时填充屏幕的一部分。 看看每个这样的UI对象包含的“Rect Transform”组件。 您也可以在屏幕上调整这些。

最后,你可以通过编程来完成。 存在Screen.heightScreen.height 。 您可以在运行时根据需要调整对象以使其工作。 我build议你不要这样做,但在某些情况下可能会有所帮助。

就我而言,我的工作就是将所有这一切都作为一个规模来创造

所以,它可以支持不pipe屏幕是

 //Find Screen resolution at the splash or loading screen float scalex = DataFactory.SCREEN_WIDTH / (float)DataFactory.OUR_FIXED_GAME_SCREEN; float scaley = DataFactory.SCREEN_HEIGHT / (float)DataFactory.OUR_FIXED_GAME_SCREEN; if (scalex >= scaley) DataFactory.SCALE = scalex; else DataFactory.SCALE = scaley; //Set all size in game at the start private int gameWidth = (int) (1400 * DataFactory.SCALE); private int gameHeight = (int) (800 * DataFactory.SCALE); private int startGameX = (int) (300 * DataFactory.SCALE); private int startGameY = (int) (280 * DataFactory.SCALE); private int objectX = (int) (410 * DataFactory.SCALE) + DataFactory.BEGIN_X; private int objectY = (int) (979 * DataFactory.SCALE) + DataFactory.BEGIN_Y; private int objectGapX = (int) (400 * DataFactory.SCALE); private int objectGapY = (int) (180 * DataFactory.SCALE); private int objectWidth = (int) (560 * DataFactory.SCALE); private int objectHeight = (int) (400 * DataFactory.SCALE); private int xRing = (int) (1005 * DataFactory.SCALE) + DataFactory.BEGIN_X; private int yRing = (int) (1020 * DataFactory.SCALE) + DataFactory.BEGIN_Y; private int radiusOutside = (int) (740 * DataFactory.SCALE); private int radiusInside = (int) (480 * DataFactory.SCALE); private int radiusObject = (int) (600 * DataFactory.SCALE); private int yObjectRing = (int) (920 * DataFactory.SCALE) + DataFactory.BEGIN_Y; 

*所有固定值都是我在单一屏幕上创build的价值*

这是我制作的3D游戏的一些示例,但是,我仍然在GUI部分使用相同的概念

在这里输入图像说明

这是我使用这个概念的一些2D游戏的例子

在这里输入图像说明

在这里输入图像说明

我知道这是一个旧post,想要为此显示一个替代scheme。 您可以尝试定义您想要缩放游戏的轴(例如,所有宽度应始终可见,高度应分别缩放到宽度):将所有场景对象存储在父级中,然后缩放父级。 防爆。 (我的宽度是固定的,高度被切掉了宽度)

 bottomRightPosition = Camera.main.ScreenToWorldPoint(new Vector3(0, 0, - Camera.main.transform.position.z)); topLeftPosition = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, -Camera.main.transform.position.z)); float Width = topLeftPosition.x -bottomRightPosition.x float scale = width / optimizedWorldDistance gameHolder.transform.localScale = new Vector3(scale,scale,1); // for 2D 

注意:我的gameHolder最初是scale(1,1,1);

你应该把所有东西放在一个主要的游戏对象中,并用一个简单的脚本(相机的东西可以帮助你检测屏幕比例)以不同的比例进行缩放。 这是我的想法。 对不起,我的英语不好。

尝试新的unity3d UI与锚定。

对于所有UI元素,您必须使用单位UI系统,这是支持多平台和纵横比的最佳方式。

以下内容是基于这篇文章的:本文所讲的内容基本上与我所说的一样:1)关于高分辨率devise,文章说:

“另一种方法是使用更高分辨率的graphics(实际上是您想要设备的分辨率最高的graphics),然后在所有设备上缩小graphics,但这不是一个好主意,因为您实际上需要更多的内存和将会在低端设备上失去性能“。

因此,devise高分辨率,然后缩小它不是好方法。

因此,正如文章所说,最好的办法是在不同的分辨率(SD,HD UD)下使用不同的图像,并在加载游戏时加载正确的图像:文章说:“最好的方法是使用不同的图像,分辨率,并在iPhone 4上使用此图像版本,在iPhone 3GS上使用低分辨率版本,这实际上是苹果公司通过使用带有@ 2x后缀文件名称的图像所做的。

以类似的方式,您可以创buildiPad 3所需的超高分辨率graphics,并附加其他后缀,并根据设备的屏幕分辨率加载正确的图像。 这就是所谓的内容缩放,因为游戏只是为了一个单一的“逻辑”场景尺寸而编写的,而所有的图像和字体都是按照设备分辨率缩放的。

所以通过使用这种方法,我们解决了具有不同分辨率的目标设备的问题。 不像喜欢说的那样,还有另外一个问题是针对具有不同宽高比的设备:从artichle:“然而,当你想瞄准不同宽高比的设备时,这种方法是不够的”

要做到这一点,我通常select一个适合我游戏devise的宽高比,并使用以下脚本在不同的设备上保持相同的宽高比:

  /* The MIT License (MIT) Copyright (c) 2014, Marcel Căşvan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using System; using System.Collections; using UnityEngine; [ExecuteInEditMode] [RequireComponent (typeof (Camera))] public class CameraFit : MonoBehaviour { #region FIELDS public float UnitsForWidth = 1; // width of your scene in unity units public static CameraFit Instance; private float _width; private float _height; //*** bottom screen private Vector3 _bl; private Vector3 _bc; private Vector3 _br; //*** middle screen private Vector3 _ml; private Vector3 _mc; private Vector3 _mr; //*** top screen private Vector3 _tl; private Vector3 _tc; private Vector3 _tr; #endregion #region PROPERTIES public float Width { get { return _width; } } public float Height { get { return _height; } } // helper points: public Vector3 BottomLeft { get { return _bl; } } public Vector3 BottomCenter { get { return _bc; } } public Vector3 BottomRight { get { return _br; } } public Vector3 MiddleLeft { get { return _ml; } } public Vector3 MiddleCenter { get { return _mc; } } public Vector3 MiddleRight { get { return _mr; } } public Vector3 TopLeft { get { return _tl; } } public Vector3 TopCenter { get { return _tc; } } public Vector3 TopRight { get { return _tr; } } #endregion #region METHODS private void Awake() { try{ if((bool)GetComponent<Camera>()){ if (GetComponent<Camera>().orthographic) { ComputeResolution(); } } }catch (Exception e){ Debug.LogException(e, this); } } private void ComputeResolution() { float deviceWidth; float deviceHeight; float leftX, rightX, topY, bottomY; #if UNITY_EDITOR deviceWidth = GetGameView().x; deviceHeight = GetGameView().y; #else deviceWidth = Screen.width; deviceHeight = Screen.height; #endif //Debug.Log("Aspect Ratio " + GetComponent<Camera>().aspect); if (GetComponent<Camera>().aspect >= 0.7f) { UnitsForWidth = 2.2f; } else { UnitsForWidth = 2f; } /* Set the ortograpish size (shich is half of the vertical size) when we change the ortosize of the camera the item will be scaled * autoamtically to fit the size frame of the camera */ GetComponent<Camera>().orthographicSize = 1f / GetComponent<Camera>().aspect * UnitsForWidth / 2f; //Get the new height and Widht based on the new orthographicSize _height = 2f * GetComponent<Camera>().orthographicSize; _width = _height * GetComponent<Camera>().aspect; float cameraX, cameraY; cameraX = GetComponent<Camera>().transform.position.x; cameraY = GetComponent<Camera>().transform.position.y; leftX = cameraX - _width / 2; rightX = cameraX + _width / 2; topY = cameraY + _height / 2; bottomY = cameraY - _height / 2; //*** bottom _bl = new Vector3(leftX, bottomY, 0); _bc = new Vector3(cameraX, bottomY, 0); _br = new Vector3(rightX, bottomY, 0); //*** middle _ml = new Vector3(leftX, cameraY, 0); _mc = new Vector3(cameraX, cameraY, 0); _mr = new Vector3(rightX, cameraY, 0); //*** top _tl = new Vector3(leftX, topY, 0); _tc = new Vector3(cameraX, topY , 0); _tr = new Vector3(rightX, topY, 0); Instance = this; } private void Update() { #if UNITY_EDITOR ComputeResolution(); #endif } private void OnDrawGizmos() { if (GetComponent<Camera>().orthographic) { DrawGizmos(); } } private void DrawGizmos() { //*** bottom Gizmos.DrawIcon(_bl, "point.png", false); Gizmos.DrawIcon(_bc, "point.png", false); Gizmos.DrawIcon(_br, "point.png", false); //*** middle Gizmos.DrawIcon(_ml, "point.png", false); Gizmos.DrawIcon(_mc, "point.png", false); Gizmos.DrawIcon(_mr, "point.png", false); //*** top Gizmos.DrawIcon(_tl, "point.png", false); Gizmos.DrawIcon(_tc, "point.png", false); Gizmos.DrawIcon(_tr, "point.png", false); Gizmos.color = Color.green; Gizmos.DrawLine(_bl, _br); Gizmos.DrawLine(_br, _tr); Gizmos.DrawLine(_tr, _tl); Gizmos.DrawLine(_tl, _bl); } private Vector2 GetGameView() { System.Type T = System.Type.GetType("UnityEditor.GameView,UnityEditor"); System.Reflection.MethodInfo getSizeOfMainGameView = T.GetMethod("GetSizeOfMainGameView",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); System.Object resolution = getSizeOfMainGameView.Invoke(null, null); return (Vector2)resolution; } #endregion } [1]: http://v-play.net/doc/vplay-different-screen-sizes/ 

这应该只是不同的长宽比问题。 现在,如果你想锚定一些游戏对象,那么如果游戏在具有不同长宽比的设备上resize,总是处于固定的位置事件,你可以使用下面的脚本:

 /*** * This script will anchor a GameObject to a relative screen position. * This script is intended to be used with CameraFit.cs by Marcel Căşvan, available here: http://gamedev.stackexchange.com/a/89973/50623 * * Note: For performance reasons it's currently assumed that the game resolution will not change after the game starts. * You could not make this assumption by periodically calling UpdateAnchor() in the Update() function or a coroutine, but is left as an exercise to the reader. */ /* The MIT License (MIT) Copyright (c) 2015, Eliot Lash Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ using UnityEngine; using System.Collections; [ExecuteInEditMode] public class CameraAnchor : MonoBehaviour { public enum AnchorType { BottomLeft, BottomCenter, BottomRight, MiddleLeft, MiddleCenter, MiddleRight, TopLeft, TopCenter, TopRight, }; public AnchorType anchorType; public Vector3 anchorOffset; // Use this for initialization void Start () { UpdateAnchor(); } void UpdateAnchor() { switch(anchorType) { case AnchorType.BottomLeft: SetAnchor(CameraFit.Instance.BottomLeft); break; case AnchorType.BottomCenter: SetAnchor(CameraFit.Instance.BottomCenter); break; case AnchorType.BottomRight: SetAnchor(CameraFit.Instance.BottomRight); break; case AnchorType.MiddleLeft: SetAnchor(CameraFit.Instance.MiddleLeft); break; case AnchorType.MiddleCenter: SetAnchor(CameraFit.Instance.MiddleCenter); break; case AnchorType.MiddleRight: SetAnchor(CameraFit.Instance.MiddleRight); break; case AnchorType.TopLeft: SetAnchor(CameraFit.Instance.TopLeft); break; case AnchorType.TopCenter: SetAnchor(CameraFit.Instance.TopCenter); break; case AnchorType.TopRight: SetAnchor(CameraFit.Instance.TopRight); break; } } void SetAnchor(Vector3 anchor) { Vector3 newPos = anchor + anchorOffset; if (!transform.position.Equals(newPos)) { transform.position = newPos; } } // Update is called once per frame #if UNITY_EDITOR void Update () { UpdateAnchor(); } #endif } 

希望这可以帮助,更多的信息,请阅读我上面链接的文章。