2014-10-06 12 views
9

Ho cercato di creare un gioco Unity 2D che supporta ogni aspetto dei dispositivi sia per Android che per tablet. C'è un modo per farlo che è stato fornito o raccomandato da Unity?Supporto di più proporzioni in Unity

risposta

0

Nel mio caso, io lavoro per creare tutti come una scala

Quindi, si potrebbe sostenere nessuna schermata materia sono

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

* tutti i fissi valorizzare è la preziosa che creo DALLA BASE sU unico schermo *

Questo è un esempio di gioco in 3D che ho fatto, però, ho ancora utilizzare lo stesso concetto in parte GUI

enter image description here

Si tratta di alcuni campioni di gioco 2D che ho usato questo concetto

enter image description here

enter image description here

+0

questo è il gioco 3D.e il mio problema non è correlato alla parte di ridimensionamento relativa al rapporto di aspetto che non può essere risolto dal semplice ridimensionamento dell'oggetto di gioco – Balu

+0

Uso anche questo concetto nel gioco 2D che ho creato ... anche con questo concetto di ridimensionamento, indipendentemente dalle dimensioni dello schermo, manterrà tutto il rapporto adeguato –

0

Lo so che è un vecchio post, volevo mostrare un'alternativa per questo. Potresti provare a definire verso quale asse vuoi scalare il tuo gioco (es .: tutta la larghezza dovrebbe essere sempre visibile, l'altezza dovrebbe ridimensionare rispettivamente alla larghezza): memorizza tutti gli oggetti scena in un genitore e ridimensiona il genitore. Es. (La mia larghezza è stata fissata e l'altezza ha tagliato fuori per la larghezza)

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 

Nota: il mio gameHolder è inizialmente di scala (1,1,1);

1

Ci sono alcune cose che dovrebbero essere considerate. Il primo è quali elementi dovrebbero essere autorizzati a scalare? Ci sono due categorie, vale a dire l'interfaccia utente e gli elementi di gioco.

La porzione Elementi di gioco può significare un sacco di cose. Se lo spazio di gioco è limitato, la chiave è in genere, inclusa una porzione generosa di "spazio negativo" o parti dell'immagine che non influiscono in modo significativo sul gioco. Ad esempio, l'immagine sottostante potrebbe essere ritagliata da sinistra e destra senza influire in modo significativo sull'immagine. Metti la parte centrale dell'immagine come elemento chiave o un lato.

enter image description here

Si potrebbe anche allungare gli elementi, anche se questo potrebbe portare ad effetti indesiderati. Avere un surplus di immagini e test con diverse razioni di aspetto è il modo migliore in genere per tali elementi di sfondo. Questi elementi di sfondo possono essere posizionati sullo sfondo, con la tela impostata su "Ridimensiona con dimensioni dello schermo" e impostando la "Modalità di corrispondenza dello schermo" sull'effetto che meglio si adatta alla tua immagine. Vedere "Canvas Scaler" per ulteriori informazioni.

Come per gli altri elementi dell'interfaccia utente, la chiave è utilizzare i punti di ancoraggio. Puoi dire a un elemento dell'interfaccia utente di prendere un numero di pixel o riempire una porzione dello schermo quando lo inserisci. Guarda il componente "Rect Transform" incluso in ogni oggetto UI. Puoi regolarli anche sullo schermo.

Infine, è possibile farlo a livello di programmazione. Esistono Screen.height e Screen.width. È possibile regolare gli oggetti come desiderato in fase di esecuzione per farlo funzionare. Ti suggerisco di non farlo per tutto, ma in alcuni casi potrebbe essere d'aiuto.

0

Si dovrebbe mettere tutto in un oggetto di gioco principale e ridimensionarlo con il rapporto di differenza utilizzando un semplice script (la fotocamera 'qualcosa' potrebbe aiutare a rilevare il rapporto dello schermo). Questa è la mia idea. Ci scusiamo per il mio pessimo inglese.

0

Prova il nuovo unity3d ui con ancoraggio.

0

Per tutti gli elementi dell'interfaccia utente è necessario utilizzare il sistema dell'interfaccia utente dell'unità, che è il modo migliore per supportare più piattaforme e proporzioni.

Il seguente contenuto è basato su this articolo: questo articolo dicono sostanzialmente le stesse cose che sto dicendo: 1) Per quanto riguarda il design SOLO nell'articolo detto alta risoluzione:

"Un altro approccio è quello di utilizzare una grafica ad alta risoluzione (di fatto lo con la risoluzione più alta del dispositivo che si desidera targetizzare) e lo ridimensionarlo su tutti i dispositivi, tuttavia non è una buona idea perché lo ha bisogno di molta più memoria e perderà le prestazioni su dispositivi terminali. "

Quindi progettare in alta risoluzione e ridimensionarlo non è un buon approccio.

Così come l'articolo detto che la cosa migliore che sia per avere immagini diverse per diversa risoluzione (SD, HD UD) e caricare l'immagine a destra quando il gioco è carico: l'articolo afferma: "L'approccio migliore è quello di utilizzare un immagine diversa con la risoluzione più alta e utilizzare questa versione di immagine su iPhone 4 e la versione a bassa risoluzione su un iPhone 3GS, che è effettivamente ciò che Apple sta facendo utilizzando le immagini con un suffisso @ 2x per il nome del file.

In modo simile, puoi creare tutta la tua grafica ad altissima risoluzione necessaria per l'iPad 3 per esempio e aggiungere un altro suffisso e caricare l'immagine giusta in base alla risoluzione dello schermo del dispositivo. il gioco è stato scritto solo per un singolo "logico" dimensione cene, e tutte le immagini & caratteri sono ridimensionate alla risoluzione del dispositivo. "

Quindi utilizzando questo approccio abbiamo risolto il problema dei dispositivi di destinazione con diverse RISOLUZIONI. No come l'articole detto c'è un altro problema che è bersaglio i dispositivi con proporzioni diverse: Dal artichle: "Tuttavia, questo approccio non è sufficiente quando si vuole indirizzare i dispositivi con proporzioni diverse"

To Non che io di solito scelgo un rapporto che può andare bene il disegno del mio gioco e utilizzare il seguente script per mantenere lo stesso rapporto di aspetto su dispositivi diversi:

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

Questo dovrebbe esclusiva il diverso problema proporzioni. Ora, se si vuole ancorare qualche gioco oggetto l'essere sempre in un evento di posizione fissa se il gioco viene ridimensionato su dispositivi con proporzioni diverse, è possibile utilizzare il seguente script:

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

Spero che questo può aiutare, per maggiori informazioni per favore leggi l'articolo che ho linkato sopra.