2014-10-06 41 views
9

Próbowałem stworzyć grę Unity 2D, która obsługuje wszystkie proporcje urządzeń dla Androida i tabletów. Czy jest jakiś sposób, aby to zapewnić lub polecić Unity?Obsługa wielu formatów w Unity

Odpowiedz

0

W moim przypadku nie działają przez tworzyć wszystko o nim jako o skali

Tak, to może wspierać żadnej ekran materia są

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

* ALL FIXED wycenione JEST wartość celna, które tworzę PRZEZ bazę na jednym ekranie *

to jakaś próba gry 3D, które zrobiłem, jednak nadal używać tego samego pojęcia w części GUI

enter image description here

To jest jakiś przykładowy gry 2d, że użyłem tego pojęcia

enter image description here

enter image description here

+0

to gra 3D.a mój problem nie jest związany z częścią skalowania związaną z proporcjami, której nie można rozwiązać przez samo skalowanie obiektu gry – Balu

+0

Używam również tej koncepcji w grze 2D, którą wykonałem ... również z tą skalą, bez względu na to, jakie są rozmiary ekranu, zachowa wszystkie proporcje, aby były prawidłowe –

0

Wiem, że to stary post, chciał pokazać alternatywę dla tego produktu. Możesz spróbować określić, do której osi chcesz skalować swoją grę (np. Cała szerokość powinna być zawsze widoczna, wysokość powinna być skalowana odpowiednio do szerokości): przechowywać wszystkie obiekty sceny w rodzica i skalować rodzica. Przykł. (moja szerokość została ustalona, ​​a wysokość została obcięta na szerokość)

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 

Uwaga: mój gameHolder jest początkowo w skali (1,1,1);

1

Jest kilka rzeczy, które należy wziąć pod uwagę. Po pierwsze, jakie elementy powinny mieć możliwość skalowania? Istnieją dwie kategorie, a mianowicie interfejs użytkownika i elementy gry.

Część Game Elements może oznaczać wiele rzeczy. Jeśli przestrzeń gry jest ograniczona, klucz jest zazwyczaj, w tym duża część "negatywnej przestrzeni" lub części obrazu, które nie wpływają znacząco na grę. Na przykład poniższy obraz może zostać przycięty z lewej i prawej strony bez znaczącego wpływu na obraz. Umieść środkową część obrazu jako kluczowy element lub jedną stronę.

enter image description here

jeden może również rozciągać się elementów, chociaż może prowadzić do niepożądanych efektów. Posiadanie nadwyżki obrazu i testowanie przy różnych porcjach rytmu jest najlepszym sposobem typowym dla takich elementów tła. Te elementy tła mogą być umieszczone w tle, a płótno jest ustawione na "Skaluj z rozmiarem ekranu" i ustaw "Tryb dopasowania ekranu" na efekt, który najlepiej pasuje do twojego obrazu. Aby uzyskać więcej informacji, patrz "Canvas Scaler".

Podobnie jak w przypadku innych elementów interfejsu użytkownika, kluczem jest użycie punktów kontrolnych. Możesz powiedzieć elementowi UI, aby wziąć albo liczbę pikseli, albo wypełnić część ekranu, kiedy ją umieścisz. Spójrz na składnik "Transformacja prostokątna" dołączony do każdego takiego obiektu interfejsu użytkownika. Możesz również dostosować te ustawienia na ekranie.

Na koniec można to zrobić programowo. Istnieje Screen.height i Screen.width. Można dostosować obiekty zgodnie z potrzebami w czasie wykonywania, aby działało. Sugeruję, że nie robisz tego dla wszystkiego, ale w niektórych przypadkach może to pomóc.

0

Powinieneś umieścić wszystko w głównym obiekcie gry i skalować go ze współczynnikiem różnicy za pomocą prostego skryptu (kamera "coś" może pomóc w wykryciu proporcji ekranu). To jest mój pomysł. Przepraszamy za mój zły angielski.

0

Wypróbuj nowy interfejs użytkownika unity3d z zakotwiczeniem.

0

Dla wszystkich elementów interfejsu użytkownika należy użyć systemu interfejsu użytkownika, który jest najlepszym sposobem obsługi wielu platform i współczynników proporcji.

Poniższa treść oparta jest na this artykułu: Ten artykuł powiedzieć zasadniczo te same rzeczy, które mówię: 1) Odnośnie projektu TYLKO w wysokiej rozdzielczości artykuł powiedział:

„Innym podejściem jest użycie grafiki o wyższej rozdzielczości (w rzeczywistości jest to z najwyższą rozdzielczością urządzenia, na które chcesz kierować) i przeskaluj ją na wszystkich urządzeniach. Jednak to nie jest dobry pomysł, ponieważ potrzebujesz dużo więcej pamięci i straci wydajność na niższym poziomie niż na urządzenia końcowe. "

Projektowanie w wysokiej rozdzielczości, a następnie skalowanie w dół to nie jest dobre podejście.

Tak jak w artykule napisano, najlepszą rzeczą jest posiadanie różnych obrazów dla różnych rozdzielczości (SD, HD UD) i załadowanie odpowiedniego obrazu podczas ładowania gry: w artykule napisano: "Najlepszym rozwiązaniem jest użycie inny obraz o wyższej rozdzielczości i użyj tej wersji obrazu na iPhonie 4 i wersji low-res na iPhonie 3GS, co jest faktycznie tym, co robi firma Apple, używając obrazów z przyrostkiem @ 2x dla nazwy pliku. W podobny sposób możesz utworzyć całą swoją grafikę w ultra-wysokiej rozdzielczości wymaganej dla iPada 3 na przykład i dołączyć inny sufiks i załadować odpowiedni obraz w zależności od rozdzielczości ekranu, jaką ma urządzenie. gra została napisana tylko dla jednego "logicznego" rozmiar cene i wszystkie obrazy są skalowane do rozdzielczości urządzenia. "

Dzięki temu podejściu rozwiązaliśmy problem urządzeń docelowych o różnych ROZWIĄZANIU. No jak articole powiedział, że jest inny problem, który ma kierować urządzeń z innych proporcjach: Z artichle: „Jednak takie podejście nie jest wystarczające, jeśli chcesz, aby urządzenia z różnymi proporcjami docelowa”

Do nie że ja zazwyczaj wybrać proporcje, które można dopasować projekt mojej grze i wykorzystać następujący skrypt, aby utrzymać ten sam współczynnik kształtu na różnych urządzeniach:

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

powinno to jedyny problem, różne proporcje. Teraz, jeśli chcesz zakotwiczyć niektóre gry przedmiotem jest zawsze w przypadku stałej pozycji, jeśli gra jest zmieniany na urządzeniach o różnych proporcjach, można użyć następującego skryptu:

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

nadzieję, że może to pomóc, aby uzyskać więcej informacji przeczytaj artykuł, który mam powyżej.