[UGUI]_1. Canvas, Event System

유니티 UI

목록 보기
1/9

해당 포스트는 고박사의 유니티 노트를 참고했습니다.

UGUI (Unity Graphic User Interface)

  • 유니티 4.6 버전 이후로 설치되어 제공하는 UI 입니다.
  • 직관적인 UI 구성요소 간의 Depth 조절이 가능합니다.
  • 캔버스 단위로 Draw Call이 관리됩니다.
  • 스프라이트 아틀라스 관리가 편리합니다.(폴더 단위로 가능)
  • 동적 할당이 쉽고 편하며 효율은 NGUI 보다 좋습니다.
  • Particle Rendering 문제가 존재합니다.
  • Tweening은 기본 제공되지 않습니다.
  • UI 확장 에셋을 쉽게 구할 수 있으며
    유니티에서 지속적으로 관리해 주기 때문에 UGUI를 사용하는 것을 권장합니다

Canvas GameObject

  • Canvas는 모든 UI요소를 배치하는 영역입니다.
  • RectTransform, Canvas, CanvasScaler, GraphicRaycaster 컴포넌트를 보유합니다.
  • Scene 뷰에 UI를 생성하면 Canvas가 함께 생성 됩니다.
  • Canvas 오브젝트는 1개의 Scene에 여러 개 존재할 수 있습니다.
  • Canvas 오브젝트에 배치되는 UI는 순서에 따라 앞에 그려 지거나 뒤에 그려집니다.
    (더 아래에 배치되는 자식이 앞에 그려집니다.)

1. Rect Transform

  • Transform을 상속받아 만든 UI 전용 Transform 입니다
  • 트랜스폼 컴포넌트와 마찬가지로 위치(position), 회전(rotation), 크기(scale)를 가지고 있으며
    사각형의 치수를 결정하는 폭(width), 넓이(height)를 가지고 있습니다.
  • 피벗(Pivot)과 앵커(Anchor)를 설정할 수 있어 UI 배치 및 관리를 더욱 편리하게 할 수 있습니다.
  • 앵커(Anchor) 수치에 따라 위치, 폭, 높이 변수가
    Left, Rihgt, Top, Bottom으로 변경되기도 합니다.
  • Rect Transform을 리사이징(resizing) 하는 경우 폭(width), 넓이(height)를 통해서 하고,
    크기(scale) 변수는 건드리지 않습니다.

- Pivot

(Pivot을 움직이기 위해서는 그림에 보이는 버튼에서 Pivot을 선택해 줘야 합니다.)

  • 피벗은 Rect Transform의 중심점입니다.
  • 중심점의 위치에 따라 위치를 설정했을때 배치되는 지점이 다릅니다.
  • Rect Transform은 피벗을 중심점으로 회전합니다.

- Anchor

  • 앵커는 부모 자식 관계의 있을 때 (두 오브젝트 모두 Rect Transform이 있어야 함)
    자신이 오브젝트가 부모의 특정 변이나 꼭짓점을 기준으로 고정되게 하는 기능입니다.
  • 부모 오브젝트의 크기가 바뀔 때 고정된 축의 여백의 거리는 그대로 유지됩니다.

  • 피벗과 다르게 앵커는 제공되는 앵커 프리셋을 이용해 앵커를 쉽게 설정할 수 있습니다.
    • 마우스 클릭 : 앵커의 위치만 움직입니다.
    • Art + 클릭 : 앵커 위치, 객체 위치가 동시에 움직입니다.
    • Shift + 클릭 : 앵커 위치, 객체 피봇이 동시에 움직입니다.
    • Art + Shift + 클릭 : 앵커 위치, 객체 피봇, 객체 위치가 전부 움직입니다.

2. Canvas

  • 캔버스 컴포넌트는 UI가 배치되고, 화면에 렌더링되는 추상 공간을 나타냅니다.
  • 랜더 모드(Render Mode)를 이용하여 UI가 화면에 렌더링 되는 방법을 설정합니다.

랜더 모드는 Screen Space (Overlay,Camera),World Space 3가지가 있습니다.
하나씩 알아보도록 하겠습니다.

- Screen Space (Overlay)

Screen Space - Overlay 모드는
캔버스의 기본 값으로 화면 전체에 항상 떠 있게 할 수 있습니다.
화면의 UI를 구성할 때 사용됩니다.
기본적으로 3D 오브젝트 보다 먼저 그려져서 항상 오브젝트 앞에 보입니다.

  • Sort Oder : Canvas 사이에서 순서를 정할 수 있습니다.
    동일한 Sort Order를 가지고 있을 경우 Hierarchy 상에서 아래에 있는
    캔버스가 앞으로 나오는데 Sort Order로 순서를 정해서
    Canvas 별 그리는 순서를 바꿀 수 있습니다.
    Sort Order가 크면 앞에 표시됩니다.

  • Target Display : 컴퓨터에는 모니터를 여러 개 연결하여 멀티 모니터를 사용할 수 있습니다.
    기본적으로 메인 모니터에만 표시하지만 만들려는
    프로그램에 따라서 여러 모니터 화면에 화면을 띄워야 될 때도 있습니다.
    이럴 경우 캔버스를 어디 모니터에 띠울지 설정할 수 있습니다.

- Screen Space (Camera)

Screen Space - Camera 모드는
카메라를 할당하여 카메라를 항상 따라다니게 할 수 있어서
카메라에 맞는 UI 화면 구성에 사용됩니다.

Overlay처럼 항상 화면에 표시할 수 있지만 Overlay 방식과 다르게
카메라를 움직였을때 오브젝트가 3D상에서 Canvas 앞쪽에 위치한다면 화면 앞에 표시할 수 있습니다.

  • Render Camera : UI 렌더링시 사용하는 카메라

  • Plane Distance : 카메라와 UI 사이의 거리입니다.
    거리가 멀어지면 그만큼 캔버스의 크기가 커집니다. 기본 값은 100입니다.

- World Space

World Space 모드는
3D 게임을 만들 때 가장 많이 사용되는 Render Mode 방식으로 3D 공간에서
3D 오브젝트를 배치하는 것처럼 자유자재로 사용할 수 있습니다.

우리에게 너무 익숙한 3D 오브젝트와 그려지는 순서가 비슷해서 3D 오브젝트
뒤에 배치하면 가려지고 앞에 배치하면 보입니다.

  • Event Camera : UI 이벤트를 처리하는데 사용되는 카메라

  • Sorting Layer / Order in Layer :
    순서를 정할 수 있는 레이어를 추가 및 설정하고 그것의 순서를 정할 수 있습니다.
    Sort Order를 사용하는 Overlay 방식을 제외하고 설정할 수 있습니다.
    기본 값은 Default에 0입니다.

참고1) Pixel Perfect

Anti-Aliasing 없이 UI를 정밀하게 렌더링 할 때 사용합니다.

캔버스 안의 요소를 픽셀과 정렬되도록 하고
RenderMode는 Screen Space(Overlay/Camera)일 때만 적용됩니다.

활성화하면 캔버스 안 요소들이 비교적 더 선명하고 흐릿한 현상을
방지할 수 있지만 요소들이 크기/회전/위치 등
애니메이션으로 동작할 때 디테일하게 조정되는 경우 비활성화하는 것이
더 부드럽게 동작하는데 유리합니다.
기본 값은 false입니다.

참고2) Additional Shader Channels

캔버스 메시를 만들 경우 이곳에서
사용할 추가 셰이더 채널의 마스크를 불러오거나 설정할 수 있습니다.

Nothing이 기본 값이고
Everything / TexCoord1 / TexCoord2 / TexCoord3 / Normal / Tangent
등으로 변경할 수 있습니다.

3. Canvas Scaler

Canvas에 배치된 모든 UI 요소의 크기, 픽셀 밀도를 제어하는데 사용합니다.

Canvas Scaler는 게임에 존재하는 모든 Scene에 사용되고 있는
Canvas 오브젝트를 모두 설정해야 합니다.

또한 Canvas Scaler의 옵션이 바뀌었을 경우 이미 배치가 되어있는
UI의 크기, 위치 등이 바뀔 수 있기 때문에 Canvas Scaler를 먼저 설정해야합니다.

- UI Scale Mode [Constant Pixel Size]


Constant Pixel Size 모드는
화면 크기에 관계없이 UI의 위치나 크기가 픽셀에 대한 단순한 배율로 지정됩니다.

화면 해상도에 의해 캔버스에 크기가 달라지면 동일한 거리 만큼을 유지하기 때문에
화면에 보이던 UI가 보이지 않을 수도 있습니다.

  • Scale Factor : Canvas 아래에 배치되는 모든 UI요소의 화면 내 배율을 나타냅니다.

- UI Scale Mode [Scale With Screen Size]

Scale With Screen Size 모드는 화면의 크기에 따라 UI의 위치나 크기가 같이 변경됩니다.
모바일 게임을 제작할 때는 기기별 화면 비율이 제각각이기 때문에 자주 사용됩니다.

  • Reference Resolution : UI의 X,Y 적정 해상도 크기를 설정 하는 변수입니다.

  • Screen Match Mode :
    Screen Match Mode는 현재 해상도의 종횡비가 Reference Resolution과 같지 않을 때
    캔버스 영역 크기를 설정하기 위해 사용되는 모드입니다.

    • Match Width Or Height :
      캔버스 영역의 Width 또는 Height를 기준으로 캔버스 영역을 설정하는 옵션입니다.
      (Match 변수는 Width 또는 Height 중 어느 쪽을 더 정확하게 맞출지 설정하게 되며 보통 0.5로 설정합니다)
    • Expand :
      캔버스 크기가 Reference Resolution 보다 작아지지 않도록
      캔버스 영역을 수평 또는 수직으로 확장하는 옵션입니다.
    • Shrink :
      캔버스 크기가 Reference Resolution 보다 커지지 않도록
      캔버스를 수평 또는 수직으로 자르는 옵션입니다.

- UI Scale Mode [Constant Physical Size]


Constant Physical Size 모드는
화면의 크기에 관계 없이 UI의 요소가 동일한 물리적인 크기로 유지되는 모드입니다.

  • Physical Unit :

  • Fallback Screen DPI :

  • Default Sprite DPI :

참고) Reference Pixels Per Unit

Image 컴포넌트를 가지는 UI의 경우 Sprite에 'Pixels Per Unit' 설정이 있다면
'Sprite의 1픽셀' = 'UI의 1 Unit'으로 설정합니다.

4. Graphic Raycaster

캔버스 오브젝트 하위에 배치된 상호작용이 가능한 UI의 요소들은
광선을 발사에 충돌 처리를 하게 됩니다

Canvas 컴포넌트의 랜더 모드가 Screen Space (Overlay)일 경우
카메라를 사용하지 않고 렌더링 과정에서 그려진 오브젝트들 위에 UI를 덧그립니다.

이때 상호작용시 Canvas 내부를 검색하는 레이 캐스터가 Graphic Raycaster이며
이벤트 시스템이 이벤트를 검출하는 수단으로 사용됩니다.

Event System

Event System 오브젝트는 Graphic Raycaster를 이용해
충돌된 오브젝트의 이벤트를 검출하는 수단으로 사용됩니다.

버튼같이 상호작용이 가능한 UI를 사용할 때 상호작용 이벤트를 처리하는 역할을 담당합니다.

  • Scene 뷰에 UI를 생성하면 Event System이 함께 생성됩니다.
  • Event System은 1개의 Scene에 하나만 존재할 수 있습니다.

IsPointerOverGameObject 활성화

IsPointerOverGameObject를 사용하기 위해서는 UnityEngine.EventSystems를 using 선언합니다.

RayCast를 이용할때 Canvas의 UI 오브젝트 위에서 (클릭/터치)하면 활성 가능한 이벤트가 실행됩니다.

하지만 RayCast가 UI를 뚫고 지나가서 게임 오브젝트에도 부딪친다면
UI와 UI뒤에있는 게임 오브젝트의 이벤트가 동시에 활성화되어 두개의 이벤트가 동시에 실행되죠.

IsPointerOverGameObject()를 이용한면 이런 문제를 해결할 수 있습니다.
IsPointerOverGameObject()는 말 그대로 포인터가 게임 오브젝트 위에 있는지를 확인하는 함수로,
게임오브젝트 위라면 false, UI 위에있다면 true를 반환합니다.

//예를들어 맵위에서 마우스 클릭시 캐릭터가 이동한다면
//마우스 클릭시 이벤트가 일어난곳 위에 작성한다.

//(UI를 클릭했다면 리턴)
if(UnitySystem.current.IsPointerOverGameObject())
	return;

Pointer Id

유니티는 Pointer Id 라는 것이 있는데
이것이 마우스 클릭과 모바일에서 터치를 구분한다.

 int clickID = eventData.pointerId;

 if (clickID == -1)
 {
     Debug.Log("마우스 왼쪽 click registered");
 }
 else if (clickID == -2)
 {
     Debug.Log("마우스 오른쪽 click registered");
 }
 else if (clickID == -3)
 {
     Debug.Log("마우스 중앙휠 click registered");
 }
 else if (clickID == 0)
 {
     Debug.Log("모바일 Single tap registered");
 }
 else if (clickID == 1)
 {
     Debug.Log("모바일 Double tap registered");
 }
 else if (clickID == 2)
 {
     Debug.Log("모바일 Triple tap registered");
 }

모바일과 컴퓨터 두종류의 플렛폼에서 동작한다면 다음과 같이 작성한다.

int PointerId;

#if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBPLAYER
PointerId = -1;
#elif UNITY_IOS || UNITY_ANDROID || UNITY_WP8 || UNITY_IPHONE
PointerId = 0;
#endif

//(UI를 클릭했다면 리턴)
if(UnitySystem.current.IsPointerOverGameObject())
	return;

0개의 댓글