Search
Duplicate

Unity/ NGUI

UI Camera

UICamera가 Input을 처리하는 방식

직접 구현하면 번거로운 것을 대신해 줘서 대단히 편리한데 이를 처리하는 방식은 아래와 같다.
모든 Input 이벤트는 NGUI의 UICamera가 처리한다.
사실 이는 당연한 방식이다. 카메라는 항상 떠 있으니까
Input이 발생하면 UICamera는 그 Input의 성격을 파악해서 이게 어떤 이벤트인지 –클릭, 더블클릭, 드래그, 드롭 등등– 파악한다.
이는 UICamera.cs의 ProcessEvents 메소드에서 일어난다.
Touch인지, Mouse인지 파악하고, Press인지 Release인지 파악하고 관련한 메소드를등등.
이벤트 타입 –3D World/ 3D UI/ 2D Word/ 2D UI– 과 충돌 타입 –Rigidbody/ Collider– 을 기준으로 Ray를 쏴서 타입에 맞는 GameObject를 가져온다.
해당 GameObject에 발생한 이벤트 –OnClick, OnPress, OnDrag 등등– 를 SendMessage로 보낸다.
SendMessage는 Unity의 함수
Input Event는 실체가 있는 것에서 발생하는 것이기 때문에 충돌한 GameObject에 메소드를 실행하게 하는 것은 매우 당연하다.
GameObject에게 SendMessage를 보내기 때문에, 딱히 UIWidget을 달고 있지 않아도 Input 처리가 가능하다.

UICamera가 처리해주는 Input 목록

OnHover
OnPress
OnClick
OnDoubleClick
OnSelect
OnDrag
OnDrop
OnInput
OnTooltip
OnScroll
OnKey

Tip

UICamera는 UI 뿐만 아니라 모든 Input 이벤트를 처리할 수 있다. 기본적으로 UICamera는 UIRoot 아래의 Camera에 달려있지만, Main Camera에 추가로 UICamera를 달면, 월드 상의 Input 이벤트 처리도 가능하다.
이러면 UICamera 클래스가 2개가 되는 셈인데, NGUI가 알아서 메인과 서브를 조절해 주므로 신경쓰지 않아도 된다.

UI Wrap Content

Wrap Content가 무한 스크롤을 구성하는 방식

Wrap Content 하위 요소들을 List에 담는다.
transform.childCount
OnMove가 –스크롤– 발생하면 WrapContent를 실행한다.
하위 transform들의 크기와 갯수를 기준으로 전체 크기를 구한다.
하위 transform들의 리스트를 모두 순회하면서 해당 transform 포지션과 Center의 포지션을 비교하여 거리를 구한다.
거리가 전체 크기를 벗어났다면 –음수 or 양수– 해당 transform의 위치를 조정한다.
수평 스크롤에 스크롤이 ‘우 -> 좌’ 로 이루어진다면 화면 왼쪽 바깥으로 빠진 transform을 화면 오른쪽 시작에 넣는다. 스크롤이 반대거나 수직인 경우엔 그에 맞게 적용한다.
만일 스크롤이 무한이 아닌 경우, 시작과 끝이 분명하다면 시작점과 끝점에서는 더 스크롤이 되면 안되므로 시작이나 끝점에서 스크롤이 막힌다.
UpdateItem()을 통해 real 데이터를 기준으로 transform의 내용을 채운다.

주의 사항

무한 스크롤에 속하는 구성 요소들은 반드시 그 크기가 같아야 한다.
Wrap Content 하위의 transform index와 transform에 들어가는 데이터의 real index를 구분해야 한다.
100개의 리스트를 100개의 transform을 만들지 않고 무한 스크롤을 통해 보여주게 하는게 Wrap Content 이므로, 화면을 채우고 약간 남는 정도의 transform 만 가지고 스크롤을 구성하는게 성능상 좋다.