게임엔진관련/유니티 엔진

[Unity] 유니티 해상도, 화면크기와 오브젝트, 3D위치 고정 매핑 관련

AlrepondTech 2019. 7. 24. 11:18
반응형

 

 

=======================

=======================

=======================

 

 

 

 

 

 

 

 

 

출처: https://jaehogame.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0-%ED%95%B4%EC%83%81%EB%8F%84%EC%97%90-%EB%A7%9E%EC%B6%B0%EC%84%9C-%EC%B9%B4%EB%A9%94%EB%9D%BC-%EC%85%8B%ED%8C%85-UI

 

Camera camera = tempUI.GetComponentInChildren<Camera>();
camera.orthographicSize = (Screen.height / (Screen.width / 16.0f)) / 9.0f;

 

자신이 개발하고 있는 유아이가 16대 9 비율로 제작 되어 있으면 다른 해상도에 맞추기 위해선

 

위와 같이 셋팅 해주면 된다.

 

(해당기기 세로 / ( 해당기기 가로 / 16 )) / 9

 

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: https://smilejsu.tistory.com/990

 

< 2D 텍스쳐 확면 꽉차게 그리기 >

유니티의 1unit은 1미터이다.

640 X 480 해상도에서 640 X 480 텍스쳐를 화면 꽉차게 그리고 싶다면 어떻게 할것인가?

카메라 orthographicSize = 세로 사이즈 / ( 유닛당 픽셀 * 2 )
                                  = 480 / ( 100 * 2 ) = 2.4

한 유닛당 100 Pixel일때 계산이다. 100픽셀이면 화면 꽉차 보이는 값이다.

이하 size는 orthographicSize와 동일한 표현이다.

가로 유닛 크기 = (가로 / 세로 ) * size * 2
                     = (640 / 480 ) * 2.4 * 2 = 6.4 m

세로 유닛 크기 = (세로 / 세로 ) * size * 2
                      = (480 / 480 ) * 2.4 * 2 = 4.8 m

코드상에서는 다음과 같이 한다.

Camera.main.orthographicSize = Screen.height / (100.0f * 2.0f)



출처: https://smilejsu.tistory.com/990 [{ 일등하이 :Unity3D }]

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: https://www.bsidesoft.com/?p=156

 

화면 크기의 문제

모바일에서 유니티를 사용하는 경우 실제 디바이스의 크기는 제각각입니다. 예를 들어 어떤 큐브를 정확히 화면의 좌측 경계에 딱 맞게 두고 싶다면 어떻게 해야할까요?

  1. 화면의 2차원상의 픽셀사이즈를 얻는다.
  2. 0,0과 pixelWidth, pixelHeight가 3D상 어떤 좌표에 해당되는지를 찾는다.
  3. 큐브를 해당 위치에 정확히 위치시킨다.

개념적으로 보면 간단히 이런 3단계면 됩니다. 하지만 여기엔 복잡한 문제가 도사리고 있습니다. 그것을 하나씩 풀어가보겠습니다.

 

화면은 카메라가 그린 것!top

결국 스크린에 보이는 모든 것은 카메라가 보고 있는 것입니다. 2D좌표가 되었든 3D좌표가 되었든 모든 열쇠는 카메라가 쥐고 있습니다. 유니티는 현재의 카메라를 참조하는 static속성을 특별한 정의 없이 사용할 수 있습니다.

private Camera _camera = Camera.main;

이 카메라는 특별한 설정이 없어도 이미 2D상의 화면 사이즈를 알고 있습니다. 다음과 같이 얻을 수 있습니다.

float screenWidth = _camera.pixelWidth;
float screenHeight = _camera.pixelHeight;

2D상의 크기는 기본적으로 주어지기 때문에 처음 할 일은 3D상의 x,y좌표를 통한 3D경계상자를 설정하는 일입니다.

 

특정 z축의 경계상자top

2D상의 화면 크기는 (0, 0)~(screenWidth, screenHeight) 까지입니다. 3D상의 경계상자는 대체 뭐라고 해야할까요?
3D상에서는 z축의 거리가 멀다면 x, y축으로 더 많이 포함될 수 있습니다. 즉 가까이에 있는 x = 100의 물체는 안보이지만 카메라로부터 멀리 떨어져있는 경우는 x = 300의 물체도 화면에 들어온다는 거죠. 따라서 카메라로 부터 z축 상 얼마나 떨어진 평면을 잘라서 x, y 축 기준의 절단면을 만든 뒤 그 절단면의 경계상자를 얻어야겠죠. 아래 그림은 이를 간단히 보여줍니다.

가장 왼쪽의 그림이 스마트폰에서 보이는화면입니다. x좌표가 300인 B만 보이고 A는 보이지 않는데 이는 카메라의 시야각 때문입니다. 이를 표현한 그림이 가운데입니다. 가장 오른쪽에는 카메라로부터 z축으로 멀리 떨어질 수록 x축 상의 더 먼 거리를 포함할 수 있다는 것을 보여줍니다. 이상에서 요점은 z축을 기준으로 경계상자를 얻어야한다는 점입니다.

2D상의 좌표를 3D상의 좌표로 변환하는 것은 카메라의 메서드인 ScreenToWorldPoint를 통해 가능합니다. 예를 들어 2D상의 좌표 x2, y2가 있고 이를 특정 z축 기반으로 변환시킨 3D상의 좌표값을 얻고 싶다면 Vector3( x2, y2, z )를 인자로 넘겨 얻을 수 있습니다. 이때 주의할 점은 z값이 절대적인 z축상의 값이 아니라 카메라와의 상대적인 거리를 의미한다는 점입니다. 이거 꼭 주의해야하는데 호스트코드에서 다시 한 번 다루겠습니다

 

public Vector3 screenTo3D( float x2, float y2, float z ){
  return _camera.ScreenToWorldPoint( new Vector( x2, y2, z ) );
}

 

이제 특정 z축을 기반으로 하는 3D상의 x,y 범위를 갖는 경계상자를 만들 수 있습니다

 

public Rect bound3D( float z ){
  Vector3 leftBottom = screenTo3D( 0, 0, z );
  Vector3 rigthTop = screenTo3D(_camera.pixelWidth,_camera.pixelHeight,z);
  return new Rect(
    //좌상단
    leftBottom.x, rigthTop.y,
    //가로길이, 세로길이
    rigthTop.x - leftBottom.x, rigthTop.y - leftBottom.y
  );
}

 

 

뭐 껌이죠. 설명하게 없습니다. 이제 이를 바탕으로 cube하나를 정확히 화면에 배치해 봅시다

 

//큐브
private GameObject cube;
 
void Start(){
  //카메라 z=-5 인 경우, 역전하면 5, 카메라로부터 5만큼 떨어진 곳은 z = 0인거죠!
  Rect bound = bound3D( -_camera.transform.position.z );
 
  cube = GameObject.CreatePrimitive( PrimitiveType.Cube );
 
  //좌상단으로 배치, 크기를 화면 꽉차게
  cube.transform.TransformPoint( new Vector3( bound.x, bound.y, 0 ) );
  cube.transform.localScale = new Vector3( bound.width, bound.height, 1 );
}
 
void Update(){
  //심심하니 돌려보자.
  cube.transform.Rotate( Time.deltaTime * angle );
}

 

 

대략 아래와 같이 되었나요.

 

결론top

이 방법은 3D로 2D를 구현하는 기초적인 시스템입니다. GUI시스템이 아니라 3D객체라도 화면 상의 정확한 위치와 크기에 가변적으로 대응하게 해주는 것이죠.

전체 소스코드는 아래에서 내려받으세요.

 
http://blog.bsidesoft.com/unity/bside000.txt
 

P.S 웹서버 마인타입 추가하기 귀찮아서..(죄송..=.=;;)

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: http://www.devkorea.co.kr/bbs/board.php?bo_table=m03_qna&wr_id=47058

 

제목처럼 3D 오브젝트를 디바이스 해상도에 따라서 꽉 차게 하고 싶은데요.

유니티에서 기본으로 제공하는 Cube를 추가해서 이것을 화면에 딱 맞게 꽉차게 만들고 싶습니다.

스크린 사이즈에 따라 스케일을 조정 하자니 큐브가 너무 커지는 상황이 생기더군요.

큐브에 스케일이 아닌 실제 크기 값으로 세팅 해야 될거 같은데

도저히 좋은 방법이 떠오르지 않네요.

좋은 방법 있으면 알려주세요.

꼭 부탁 드립니다.

 

-------------------------------------------------------------------------------------------------------------------------------------------------------

 

일정 비율을 찾으셔서 쓰시는건 어때요? 
예를들어, 
cube.localScale = new Vector3(Screen.width * 0.1f(상수), Screen.width * 0.1f(상수), Screen.width * 0.1f(상수)) 
을 했을때, 화면에 딱 맞게 만들어졌다고 치면, 다른 사이즈에서도 맞게 될겁니다.

 

 

 

=======================

=======================

=======================

 

 

 

반응형

 

728x90

 

 

 

출처: http://www.silverwolf.co.kr/unity3d/79851

 

해상도 설정

모바일 기기와 OS에 따라 해상도 설정 방법이 다르다.
<  안드로이드 설정 >
Screen.SetResolution(int width, int heignt, bool bFullScreen)
640×480 해상도 일 경우, SetResolution(600, 480, true)

< IOS 설정 >
유니티 4.0 이상에서만 SetResolution( ) 사용 가능
File / Build Settings / Player Settings / Other Setting에서 Target Resolution을 Native, Standard, HD 중에서 선택

< 안드로이드 기기 대응 >
모든 기기에 맞게 화면 설정을 할 수 없기 때문에, 해상도를 비율을 맞게 화면이 맞게 보이도록 한다.
2:3 비율로 개발 한다면 
SetResolution( Screen.width, Screen.width * 3 / 2, ture )로 한다.

< 2D 텍스쳐 확면 꽉차게 그리기 >
유니티의 1unit은 1미터이다.
640 X 480 해상도에서 640 X 480 텍스쳐를 화면 꽉차게 그리고 싶다면 어떻게 할것인가?
카메라 orthographicSize = 세로 사이즈 / ( 유닛당 픽셀 * 2 )
                                  = 480 / ( 100 * 2 ) = 2.4

한 유닛당 100 Pixel일때 계산이다. 100픽셀이면 화면 꽉차 보이는 값이다.
이하 size는 orthographicSize와 동일한 표현이다.
가로 유닛 크기 = (가로 / 세로 ) * size * 2
                     = (640 / 480 ) * 2.4 * 2 = 6.4 m

세로 유닛 크기 = (세로 / 세로 ) * size * 2
                      = (480 / 480 ) * 2.4 * 2 = 4.8 m

코드상에서는 다음과 같이 한다.
< 2D 급조 테스트 >
안드로이드에서 급하게 해상도 테스트를 하였다.
테스트 해상도를 640 X 480에서 작업 하였기 때문에 모바일 기기 해상도를 강제로 640 X 480으로 설정하였다. 머리 굴려서 계산식이 통하지 않아서 아래처럼 기냥 하였다.

Screen.SetResolution( 640, 480, true );        
Camera.main.orthographicSize = 480 / (100.0f * 2.0f);

머리가 맑을때 더 우아한 방법을 찾아 봐야겠다.
< 안드로이드 기기 해상도 >
480 x 800 : 갤럭시S, 갤럭시S2, 옵티머스 2X, Nexus S, Nexus One, HTC Desire HD, HTC Desire HD2
800 x 1280 : 갤럭시탭 10.1, 갤럭시노트1, 넥서스 7
720 x 1280 : 갤럭시S3, 갤럭시S2 HD, 갤럭시노트2, 옵티머스G
1200 x 1920 : 넥서스 7(2013)
1080 x 1920 : G2, 갤럭시S4, 갤럭시노트3

< iOS 기기 해상도 설정 >
320 x 480 : 아이폰 3
640 x 960 : 아이폰 4
640 × 1136 : 아이폰 5
768 x 1024 : 아이패드1, 아이패드2, 아이패드 미니
1536 x 2048 : 아이패드3, 아이패드4

< 기기들의 화면비율 >
(3:4) : 768 x 1024(아이패드 1), 1536 x 2048(아이패드 3)
(2:3) : 320 x 480(아이폰 3, 옵1), 640 x 960(아이폰 4)
(10:16) : 800 x 1280(넥7, 갤탭10.1, 갤노1), 1200 x 1920(넥7_2013)
(3:5) : 480 x 800(넥원, 갤2)
(9:16) : 640 × 1136(아이폰 5), 720 x 1280(갤3, 옵G, 갤노2), 1080 x 1920(G2, 갤4, 갤노3)

< Windows 환경 Satandalone 해상도 수정 >
메뉴 / File / BuildSettings / Platform을 PC, Mac & Linux Standalone으로 설정  / Player Settings... 버튼 클릭  / Inspector View / Resolution And Presentation 설정



출처: https://smilejsu.tistory.com/990 [{ 일등하이 :Unity3D }]

 

카메라 사이즈와 Pixels Per Unit에 대해서

 

유니티 2D의 기본 설정은 카메라 사이즈가 5로 되어있고 Pixels Per Unit은 100으로 되어 있습니다.

 

이걸 냅둔채로 도트 그래픽 게임을 만들려고 하면 상당히 힘듭니다.

 

그리고 그 힘든 상태로 제가 하고 있었지요.

 

모바일을 염두해서 9:16 비율로 하니까 좌우가 -2.62~2.62였나, 아무튼 이런 작으면서도 애매한 크기를 가진데다 UI 캔버스로 UI를 배치하면 그건 또 1080 x 1920 비율로 이루어지니 헷갈리기도 하고 다루기가 많이 불편합니다.

 

그래서 개선시키고자 알아보니 저 둘을 바꿔줄 필요가 있고 Pixels Per Unit은 3D 모델 다룰 때의 Scale factor와 비슷한 기능이라는 것을 알았습니다.

 

먼저 카메라 사이즈의 경우 크게 2가지의 용도에 따라 다르게 수치를 입력합니다.

 

1도트, 혹은 일정 크기를 1로 잡을 것인지, 실제 목표 해상도와 일치시킬 것인지.

 

전자의 경우 맵이 넓고 움직이거나 블록 단위로 무언가를 할때 제작에 용이합니다. 전반적으로 상대적인 요소를 많이 다룰 때 쓰면 좋으며 유니티 거리 1단위의 변화가 중요할 수록 카메라 사이즈를 작게 하면 됩니다.

 

후자의 경우는 화면이 거의 움직이지 않거나 정적인 공간 내에서 무언가를 할 때 용이합니다. 전반적으로 절대적인 요소를 다룰 때 편하며 1단위의 변화보단 실제 크기와의 동기화가 중요할 때 좋습니다.

 

이 게임의 경우 대체적으로 정적인 공간 내에서 게임이 이루어지기 때문에 후자를 선택했습니다.

 

UI 캔버스 내에서 UI배치와 일치시켜 개발 환경을 보다 편하게 만들고 게임적으로도 상대적인 요소들을 활용할 부분들이 그리 많지 않기 때문입니다.

 

그래서 후자일 때 카메라 사이즈의 공식은 (목표 해상도 높이/2) 이기에 960으로 주었습니다.

 

이렇게 되면 카메라의 위치가 0, 0이고 게임뷰의 비율이 9:16이라는 가정 하에 x는 -540~540, y는 -960~960내에서 좌표를 가집니다.

 

만약 0~1080, 0~1920으로 가지게 하고 싶으면 카메라의 위치 각각 540, 960 만큼을 옮기시면 됩니다.

 

 

이어서 Pixels Per Unit의 경우 거리 1당 몇개의 픽셀을 뿌릴 것이냐는 말입니다.

 

만약 1x1 짜리 이미지를 유니티에서 불러와 Pixels Per Unit을 1로 설정한 후 2D Sprite로 그려보면 Scale이 1, 1 이라는 가정 하에 유니티 거리로 1x1만큼의 크기로 그려져 있는 것을 볼 수 있습니다.

 

3D 모델링의 Scale factor처럼 원본 파일에 직접 세팅해 주는 요소이기 때문에 다른 2D 이미지들간의 해상도가 있어도 관리하기 편하게 해줍니다.

 

위 카메라 사이즈 설정과 더불어 이 둘을 같이 설정해 주면 이후 작업환경에 많이 편해집니다.

 

 

 

이해를 돕기위한 gif

 

1x1 크기의 이미지를 Pixels Per Unit을 1로 설정한 후 x축으로 -1, y축으로 -2만큼 1씩 이동시킨 모습.

 

 

Icicle Game의 경우 환경은 1080x1920이지만 전반적인 그래픽은 그의 20%인 216x384 크기 내에서 그려집니다.

 

여기서 Pixels Per Unit을 1로 잡으면 오브젝트를 전부 5배로 크게 해주어야 할 필요가 있지만 Pixels Per Unit를 0.2로 잡아두면 알아서 5배로 커져서 그려집니다.

 

만약 특정 부분엔 더 고퀄리티가 요구되어 1080x1920 크기의 30%나 그 이상의 해상도로 그려진게 있더라도 Pixels Per Unit을 그에 맞춰 설정하면 별도의 스케일 조정 없이 게임 내에선 동일한 크기로 그려지는 이미지들을 볼 수 있습니다.

 


출처: https://kupaprogramming.tistory.com/41 [공룡 프로그래밍]

 

 

 

=======================

=======================

=======================

 

 

 

출처: https://doo9713.tistory.com/35

 

 

 유니티를 사용하면서 항상 유동적인 해상도 때문에 고민한 적이 많았었다. 첫 유니티 포스팅으로 단순하지만 나중에 잊어버릴거 같아서 해상도에 따른 오브젝트 위치 설정을 포스팅 하려한다. ugui의 경우는 단순하게 Anchor를 활용해서 할 수 있지만 게임 오브젝트의 경우는 내가 못 찾는 것인지는 모르겠지만 그런 기능이 없다.

 

 

Camera.main.orthographicSize : orthographic모드일 때 카메라 수직 크기의 절반을 반환

Screen.width, Screen.height : 창의 픽셀 크기

 

 실제 카메라의 크기가 픽셀 크기가 아니기 때문에 화면의 비율과 카메라의 수직 크기를 이용해 수평의 크기를 구한다.

 


 

 

 

 실행결과를 보면 해상도에 상관없이 항상 좌하단과 우상단에 오브젝트가 위치한다.

 

 

※ 카메라가 orthographic모드일 때 사용하는데 perspective모드에서도 얼추 비슷한 위치에 나온다.

 

 

 

=======================

=======================

=======================

 

 

 

 

반응형