일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 스레드전용저장소
- 구문트리
- unity
- CS정리
- 백준
- 다익스트라
- 알고리즘
- vector
- 코드포스
- c++
- 심벌 해석
- 컴파일러
- 선형대수학
- 링커
- matrix
- 동적링크
- 정적링크
- 행렬
- column space
- Rust
- 다이나믹 프로그래밍
- 재배치
- 스레드전용리소스
- 대상파일
- rust 스터디
- 적재도구loader
- linear algebra
- 컴퓨터밑바닥의비밀
- 벡터
- eigenvalue
- Today
- Total
개발_기록용
[Unity] 특정 영역 위로 마우스 오버 시 커서 이미지 변경하기 본문
1. 개요
인디게임 내에서 컴퓨터 모니터와 리더기 등을 구현하고
특정 영역에서는 돋보기 커서가, 특정 영역에서는 모래 시계 커서가 뜨도록
개발해야 하는 상황이 생겼다.
요약하면 아래와 같은 상황으로 개발하는 것!
2. 생각
구현 단계를 다음과 같이 쪼개보겠다.
- 일단 2D 화면에서 마우스의 현재 위치를 받아서
- 마우스가 특정 영역에 들어갔는지 체크한다.
마우스의 현재 위치 받아오기
우선, 현재 화면에서 마우스의 현재 위치를 받는 방법은 굉장히 다양하다.
특별히 가공없이 바로 위치값을 받아오려면
- Input.mousePosition
- Event.current.mousePosition 이 있다.
참고로, Input.mousePosition과 Event.current.mousePosition의 차이는
아래 포스팅에서 다루겠다.
나는 Input.mousePosition을 사용했다.
(그 이유는 아래 내용에서 밝히겠다.)
마우스가 특정 영역에 들어갔는지 체크하기
특정 영역에 마우스에 의한 Event가 들어갔는지를 체크해야 하므로
다음과 같은 방법을 사용할 수 있다.
1. Event Trigger 사용 : 가장 간단한 방법이다. Image나 Button처럼 Event System으로 Event를 잡아낼 수 있는 오브젝트를 배치하고, 거기에 Event Trigger 컴포넌트를 배치해 OnMouseOver(), OnMouseExit() 등의 함수를 사용한다.
2. Raycast target과 버튼 : UI Component 아래의 모든 오브젝트들은 raycast의 대상이 되도록 Raycast target을 활성화해놓으면 사용자와 상호작용 할 수 있다. 그리고 2D 에선 Physics.Raycast나 RaycastHit2D, GraphicRaycaster.Raycast 등의 함수를 사용한다.
해당 방식들의 문제점
그러나, 1번과 2번을 사용했을 경우
마우스 체크용 객체 위로 또다른 UI 오브젝트가 올라오면
해당 오브젝트에 먼저 Event와 Raycast가 잡힐테니 작동하지 않을 우려가 있었다.
위와 같은 상황이라면 Button에 마우스를 가져다 댔을 때
녹색 영역이 아닌 Button이 먼저 선택되어마우스의 영역을 체크하는 용도의 녹색 영역을 사용할 수 없게 된다.
해결 방법
그래서 나는 이를 해결하기 위해 내가 원하는 위치와 사이즈로
Rect를 생성하고, 그 Rect에 마우스가 올라왔는지 체크하도록 했다.
내가 Unity에서 영역 체크 용도로 사용할 영역을 Image로 받아오고
그 아래에는 커서로 할당할 이미지와 만들 Rect를 선언해주었다.
각 Rect는 내가 Image로 받아온 영역의 rectTransform의 pivot 정보를 먼저 받아 저장하고
해당 Rect의 world 상의 position을 가져와 pivot에 Screen의 가로, 세로 크기를 이용해 계산하여
내가 다룰 Rect의 position으로 할당해주었다.
1. rectTransform의 pivot을 받아온 이유
: 좌측 상단에 고정 등 해상도 대응을 위해 pivot을 기존 (0.5, 0.5)에서 (1, 0) 등으로 바꾼 경우,
position 값으로 받아와 내가 다룰 rect에 할당할 때
내가 그릴 rect의 pivot과 받아오는 rect의 pivot이 달라 위치의 차이가 난다.
2. localPosition이 아닌 그냥 position을 받아오고 할당하는 이유
: localPosition은 그 오브젝트의 parent와 상대적 위치이므로, 실제 게임 화면에서의
절대 위치와 차이가 난다. 그래서 절대 위치인 position을 사용.
그리고 OnGUI 함수 안에는 이런 식으로 작성해서
내가 만든 Rect 안에 마우스 포지션이 들어왔는지 여부를 체크하도록 했다.
**여기서 Event.current.mousePosition을 쓰면 GUI 좌표계로 전달되어
왼쪽 위가 (0, 0)인 상태로 넘어온다.
반면, Input.mousePosition을 쓰면 화면 좌표계로 전달되어
왼쪽 아래가 (0, 0)인 상태로 넘어오므로 Input.mousePosition을 쓰게 되었다.
3. 결과
맨 처음에 의도한 것대로 잘 제작되었다!
혹시나 해당 방법으로 예상치 못한 이슈가 발생하면
그때 추가로 다른 포스트를 작성해보겠다!
'유니티' 카테고리의 다른 글
유니티 내부로 OBJ 파일 import 가능한 RunTime OBJ Importer 에셋 (0) | 2025.01.07 |
---|---|
[Oculus Quest 3에서 Unity에 Hand Tracking 적용하기] (5) | 2024.08.08 |
OpenUPM의 패키지 Unity로 Import하기 (1) | 2024.04.01 |
유니티 2022.1 버전 AndroidManifest.xml 위치 (0) | 2022.07.21 |