UI 자동화(3)

개발조하·2023년 12월 28일
0

Unity

목록 보기
16/30
post-thumbnail

1. Event() 연동

이전 포스팅에서 Bind()로 원하는 컴포넌트/게임오브젝트를 찾고, Get()으로 출력을 했다. 이제 버튼을 클릭하면 점수가 오르는 등의 이벤트도 자동화로 연결해보자.

1.1 EventSystem 사용

1.1.1 EventSystem 사용 사례 1

이전에 UI_Button.cs에서 Button을 클릭하면 score++되도록 코드를 작성하였다.
이때, 클릭한 위치로 Player가 이동하는 InputManager.cs의 코드에 따라 Button을 클릭할 때에도 Player가 해당 위치로 이동하는 문제가 발생한다.

-> InputManager.cs를 아래와 같이 수정하여 클릭 인식에 있어서 UI 오브젝트와 게임 환경을 분리!

이때, 사용되는 것이 EventSystem이다.

💡 EventSystem.current.IsPointerOverGameObject()의 기능
  • UI 상호작용 확인: 사용자의 포인터(마우스, 터치 등)가 현재 UI 요소 위에 있는지를 확인합니다. 이는 버튼, 슬라이더, 드롭다운 메뉴 등의 UI 요소를 포함할 수 있습니다.
  • 입력 처리 결정: 이 함수를 통해 개발자는 포인터가 UI 요소 위에 있을 때만 특정 동작을 수행하도록 할 수 있습니다. 예를 들어, 플레이어가 게임 환경을 클릭하려고 할 때 실수로 UI 요소를 클릭하는 것을 방지할 수 있습니다.

ex)

  • UI 클릭 제한: 게임 내에서 플레이어가 오브젝트를 선택하거나 조작하려고 할 때, EventSystem.current.IsPointerOverGameObject() 함수를 사용하여 포인터가 실제 게임 환경 위에 있는지, 아니면 UI 요소 위에 있는지를 체크하여, UI 요소 위에서는 플레이어의 입력을 무시할 수 있습니다.
  • 드래그 앤 드롭 UI: 드래그 앤 드롭 인터페이스를 구현할 때, 이 함수를 사용하여 사용자가 특정 UI 요소를 드래그하는 중인지 여부를 확인할 수 있습니다.

1.1.2 EventSystem 사용 사례 2

하이어라키에 UI오브젝트를 생성하면 자동으로 EventSystem이 함께 생성되고, 인스펙터창에서 보면 Event System 컴포넌트가 추가되어 있는 것을 볼 수 있다.

즉, UI 관련 Event 연동은 Unity 내부의 EventSystem클래스를 활용하면 된다!!!

1.2 UI_EventHandler.cs 생성

인스펙터에서 UI별로 실행할 Event를 드래그앤드롭으로 연결하지 않고, 스크립트를 생성하여 자동화하자.

  • Image 드래그하여 옮기는 기능 구현하기

1.2.1 IBeginDragHandler, IDragHandler 적용

만약 OnBeginDrag 콜백을 받고 싶다면 구현해야 할 인터페이스이다. IBeginDragHandler 외에도 IDragHandler를 구현해야 한다!
(ex. 인벤토리에서 아이템 드래그 기능에서 사용)

  • Alt + Enter로 '인터페이스 구현'하기

UI_EventHandler.cs를 UI_Button(Canvas)에서 제거하고, Image 객체에 붙여주면,
OnDrag()에 작성한 transform.position = eventData.position; 코드로 인해 Image를 잡고 드래그하면 Image가 움직이는 것을 확인할 수 있다.

💡 핸들러 델리게이트 선언

위의 코드를 델리게이트를 통해 구현해보자.

Action<PointerEventData> onBeginDragHandler = null;
Action<PointerEventData> onDragHandler = null;

이 두 라인은 PointerEventData 타입의 매개변수를 받는 Action 델리게이트를 선언한다. 이 델리게이트는 드래그 시작(onBeginDragHandler)과 드래그 중(onDragHandler) 이벤트에 대한 콜백 함수를 참조한다.
-> eventData의 값에 따라서 드래그하는 Image도 함께 이동할 수 있게 된다.

이 방식을 사용하면 UI_EventHandler 클래스는 드래그 이벤트에 대한 구체적인 로직을 직접 구현하지 않고도, 다른 클래스나 메서드에서 정의된 로직을 유연하게 적용할 수 있다. 이는 코드 재사용성과 유지 보수성을 높이는 좋은 방법이다!

1.3 AddUIEvent()_UI Event 연동

💡 Define.cs

💡 Util.cs

💡 UI_EventHandler.cs

ㄴ 기존 IBeginDragHandler는 나중에 필요할 때 사용하고, 현재는 Click과 Drag가 필요하기 때문에 IPointerClickHandler인터페이스를 구현하였다.

💡 UI_Base.cs

ㄴ AddUIEvent(객체, 참조 함수, UIEvent 타입)으로 UI에 해당 Event 연동하는 함수 생성

💡 UI_Button.cs

ㄴ UI_Button 스크립트에서 Bind()로 맵핑한 ItemIcon를 GetImage()로 출력하고, AddUIEvent()로 해당 Image를 클릭&드래그하면 Image가 따라가도록 Event를 연동했다.

1.4 Extension 메서드 사용하기

현재는 UI마다 AddUIEvent()를 별도로 추가해줘야 한다.
이를 아래 이미지처럼 UI객체에 바로 AddUIEvent()를 붙여 바로 연동시킬 수는 없을까?

💡 Extension 메서드를 사용하면 된다.

1.4.1 Extension.cs 생성

UI_Button.cs

-> 필드에 Text와 Button 객체를 [SeralizeField]로 불러오고, 인스펙터에서 실행할 Event를 연결해주고, 해당 UI객체도 연결해줘야 했는데 이렇게 작성하면 코드만으로 UI 자동화를 구현할 수 있다.

-> 최종 실행하면 Button을 클릭했을 때 점수가 1점씩 증가하고, 중앙 ItemIcon을 잡아 드래그하면 이동하는 것을 확인할 수 있다.

  • GetorAddComponent()도 자주 사용하기 때문에 Extension 메서드로 바꿔줌

📄참고자료
[인프런] c#과 유니티로 만드는 MMORPG 게임 개발 시리즈_3. 유니티 엔진
Unity Documents_UnityEngine.EventSystems
Unity Documents_IBeginDragHandler
Unity Documents_IDragHandler

profile
Unity 개발자 취준생의 개발로그, Slow and steady wins the race !

0개의 댓글