계속 UI 와 3D 오브젝트 가 같이 있으면 3D 오브젝트 가 먼저 선택되는 이슈가 있었다. 헷갈려서 이참에 정리해둠
1. UI 시스템
- 기본적으로 GraphicRaycaster 및 EventSystem 을 사용한다.
- UI 요소에 대한 레이캐스트는 3D 오브젝트의 레이캐스트보다 먼저 수행된다.
- 여기서 UI 요소란, 일반적으로 Canvas 게임 오브젝트 아래의 오브젝트들을 의미한다. 하지만 모든 게 대상은 아니다.
1.1. 주요 UI 요소들
- Graphic 컴포넌트를 가진 오브젝트(Image, Text, RawImage)
- Selectable 컴포넌트를 상속받은 오브젝트(Button, Toggle, Slider, Dropdown)
- CanvasRenderer 컴포넌트를 가진 오브젝트들
2. 관련 메서드
- Physics.Raycast 는 3D 공간의 콜라이더에 대해 작동한다. UI요소를 감지하지 않는다.
- EventSystem.current.RaycastAll 는 UI를 포함한 충돌하는 모든 요소를 감지한다.
내 경우는 이 개념들이 좀 헷갈려서 아예 전체를 레이캐스트한 다음, Canvas 위의 요소들만 감지하는 식으로 UI 요소들을 구분했다.
cs
// 1. UI 요소를 클릭했는지 점검
PointerEventData pointerData = new PointerEventData(EventSystem.current);
pointerData.position = Input.mousePosition;
List<RaycastResult> allResults = new List<RaycastResult>();
EventSystem.current.RaycastAll(pointerData, allResults); // EventSystem을 이용, 전체를 레이캐스ㅌ
// UI 요소만 필터링(GraphicRaycaster를 갖고 있는 것들만)
List<RaycastResult> uiResults = allResults.Where(r => r.module is GraphicRaycaster).ToList();
// 2. UI 요소가 클릭되었다면 해당 UI 요소 실행
// 일단 버튼에 대해서만 구현
foreach (var result in uiResults)
{
Button button = result.gameObject.GetComponent<Button>();
if (button != null)
{
button.onClick.Invoke();
break;
}
}
3. Canvas 설정
이외에도 Canvas의 설정에 따라 반응이 달라질 수 있다고 한다.
- Overlay : UI 요소가 항상 3D 오브젝트보다 위에 렌더링, 레이캐스트도 우선적으로 처리된다.
- Camera : UI 요소가 3D 공간 위에 렌더링되며, 특정 카메라에 연결된다.
- World Space : UI가 3D 공간 내에 존재하며, 다른 3D 오브젝트와 동일하게 취급될 수 있다.
내 경우는 World Space로 구현된 상태에서, EventSystem에 의한 레이캐스트가 먼저 반응은 하지만 버튼 클릭이 작동은 하지 않는 식이었던 것 같음.
지금 유니티 개인 프로젝트를 하면서 느끼는 건, 어디선가 한 번 꼬이기 시작하면 다른 곳들에서 뜬금없이 문제가 같이 발생해서 찾기가 어렵다는 게 있겠다. 웹 등 다른 프로젝트를 할 때는 못 느낀 건데, 유니티가 유독 심한 느낌임.
'Work, Study > Unity' 카테고리의 다른 글
241224 회전하는 화살 구현하기 (0) | 2024.12.24 |
---|---|
241129 투명 이미지를 마스크로 사용하기 (0) | 2024.11.29 |
Awake, OnValidate, Initialize 차이점 (0) | 2024.07.29 |
직렬화, 프로퍼티와 필드 (0) | 2024.07.29 |