2014-10-06 18 views
9

我一直在嘗試創建一款Unity 2D遊戲,支持Android和平板電腦的各種設備的縱橫比。有沒有辦法做到這一點,由Unity提供或推薦?在Unity中支持多種高寬比

回答

0

以我爲例,我做的工作通過創建所有的它作爲一個規模

因此,它可以支持,無論屏幕是

//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; 

*所有固定看重的是被重視的,我CREATE通過鹼基對單個屏幕*

這是3D遊戲的一些樣品,我提出,不過,我還是用同樣的概念在GUI部分

enter image description here

這是2D遊戲的一些樣品,我用這個概念

enter image description here

enter image description here

+0

這是3D遊戲。和我的問題是無關的縮放部分其相關的長寬比,只是縮放遊戲對象無法解決 – Balu 2014-10-06 14:07:59

+0

我也在2D遊戲中使用這個概念,我做了...... 也與這個縮放概念,不管屏幕尺寸是多少,它都會保持所有的比例 – 2014-10-06 18:35:31

0

我知道這是一個老帖子,想表現這種替代。你可以嘗試定義你想要縮放遊戲的軸(例如,所有寬度應始終可見,高度應分別縮放到寬度):將所有場景對象存儲在父級中並縮放父級。例如, (我的寬度是固定的,高度得到了切斷爲寬度)

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最初規模(1,1,1)的;

1

有幾件事情應該考慮。首先是什麼元素應該允許規模?有兩個類別,即UI和遊戲元素。

遊戲元素部分可能意味着很多東西。如果遊戲空間有限,關鍵是典型的,包括「負面空間」的大部分,或圖像中不會影響遊戲效果的部分。例如,下面的圖像可以從左側和右側裁剪,而不會顯着影響圖像。將圖像的中心部分作爲關鍵元素或一側。

enter image description here

人們還可以舒展的元素,儘管這可能會導致不良影響。對於這樣的背景元素來說,通過不同方面口糧的形象和測試是最好的方式。這些背景元素可以放置在背景中,畫布被設置爲「按屏幕尺寸縮放」,並將「屏幕匹配模式」設置爲最適合您圖像的效果。有關更多信息,請參閱「Canvas Scaler」。

至於其他UI元素,關鍵是要使用錨點。您可以告訴UI元素採用多個像素,或者在放置時填充屏幕的一部分。查看每個此類UI對象附帶的「Rect Transform」組件。您也可以在屏幕上調整這些。

最後,你可以通過編程來完成。存在Screen.heightScreen.width。您可以在運行時根據需要調整對象以使其正常工作。我建議你不要這樣做,但在某些情況下可能會有所幫助。

0

您應該將所有內容放在主遊戲對象中,並使用一個簡單的腳本(相機'東西'可以幫助您檢測屏幕比例)以差異比例對其進行縮放。 這是我的想法。 對不起,我的英語不好。

0

嘗試新的unity3d用戶界面與錨定。

0

對於所有UI元素,您必須使用單位UI系統,這是支持多平臺和縱橫比的最佳方式。

下面的內容是基於this文章: 這篇文章說基本上是我說同樣的事情: 1) 僅關於高分辨率的文章說設計:

「的另一種方法是使用更高分辨率的圖形(實際上是您想要設備的最高分辨率的 ),並且 會在所有設備上縮小它。但是,這不是一個好主意,因爲 您實際上需要更多的內存和會在 低價位表現失色,終端設備「。

因此,設計高分辨率,然後縮小它不是好方法。

因此,作爲文章說的最好的事情是,爲不同分辨率(SD,HD UD)不同的圖像,並加載正確的圖像時,遊戲是加載:文章說: 「最好的方法是使用一個具有更高分辨率的不同圖像,並在iPhone 4上使用此圖像版本,在iPhone 3GS上使用低分辨率版本,這實際上是蘋果公司通過使用帶有@ 2x後綴文件名的圖像所做的事情。以類似的方式,您可以創建iPad 3所需的所有超高分辨率圖形,並添加另一個後綴,並根據設備的屏幕分辨率加載正確的圖像,這稱爲內容縮放,如同該遊戲僅爲單個「邏輯」寫入字號大小,並且所有圖像&字體都縮放到設備分辨率。「

所以通過使用這種方法,我們解決了具有不同分辨率的目標設備的問題。 沒有像articole說,還有另外一個問題,就是針對不同的寬高比設備: 從artichle: 「但是,如果你想針對不同的縱橫比的設備,這個做法是不足夠的」

要這樣做,我通常選擇的寬高比,能適合我的遊戲的設計和使用下面的腳本,以保持在不同設備上相同的寬高比:

/* 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/ 

這應該唯一不同的縱橫比的問題。現在如果你想錨定一些遊戲對象,如果比賽是在不同的縱橫比的設備調整在固定位置事件始終,您可以使用下面的腳本:

/*** 
* 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 
} 

希望這可以幫助,以獲得更多信息請閱讀我上面鏈接的文章。