이전 포스팅에서 Bind()로 원하는 컴포넌트/게임오브젝트를 찾고, Get()으로 출력을 했다. 이제 버튼을 클릭하면 점수가 오르는 등의 이벤트도 자동화로 연결해보자.
이전에 UI_Button.cs에서 Button을 클릭하면 score++되도록 코드를 작성하였다.
이때, 클릭한 위치로 Player가 이동하는 InputManager.cs의 코드에 따라 Button을 클릭할 때에도 Player가 해당 위치로 이동하는 문제가 발생한다.
-> InputManager.cs를 아래와 같이 수정하여 클릭 인식에 있어서 UI 오브젝트와 게임 환경을 분리!
이때, 사용되는 것이 EventSystem이다.
💡 EventSystem.current.IsPointerOverGameObject()의 기능
ex)
하이어라키에 UI오브젝트를 생성하면 자동으로 EventSystem이 함께 생성되고, 인스펙터창에서 보면 Event System 컴포넌트가 추가되어 있는 것을 볼 수 있다.
즉, UI 관련 Event 연동은 Unity 내부의 EventSystem클래스를 활용하면 된다!!!
인스펙터에서 UI별로 실행할 Event를 드래그앤드롭으로 연결하지 않고, 스크립트를 생성하여 자동화하자.
만약 OnBeginDrag 콜백을 받고 싶다면 구현해야 할 인터페이스이다. IBeginDragHandler 외에도 IDragHandler를 구현해야 한다!
(ex. 인벤토리에서 아이템 드래그 기능에서 사용)
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 클래스는 드래그 이벤트에 대한 구체적인 로직을 직접 구현하지 않고도, 다른 클래스나 메서드에서 정의된 로직을 유연하게 적용할 수 있다. 이는 코드 재사용성과 유지 보수성을 높이는 좋은 방법이다!
ㄴ 기존 IBeginDragHandler는 나중에 필요할 때 사용하고, 현재는 Click과 Drag가 필요하기 때문에 IPointerClickHandler인터페이스를 구현하였다.
ㄴ AddUIEvent(객체, 참조 함수, UIEvent 타입)으로 UI에 해당 Event 연동하는 함수 생성
ㄴ UI_Button 스크립트에서 Bind()로 맵핑한 ItemIcon를 GetImage()로 출력하고, AddUIEvent()로 해당 Image를 클릭&드래그하면 Image가 따라가도록 Event를 연동했다.
현재는 UI마다 AddUIEvent()를 별도로 추가해줘야 한다.
이를 아래 이미지처럼 UI객체에 바로 AddUIEvent()를 붙여 바로 연동시킬 수는 없을까?
💡 Extension 메서드를 사용하면 된다.
UI_Button.cs
-> 필드에 Text와 Button 객체를 [SeralizeField]로 불러오고, 인스펙터에서 실행할 Event를 연결해주고, 해당 UI객체도 연결해줘야 했는데 이렇게 작성하면 코드만으로 UI 자동화를 구현할 수 있다.
-> 최종 실행하면 Button을 클릭했을 때 점수가 1점씩 증가하고, 중앙 ItemIcon을 잡아 드래그하면 이동하는 것을 확인할 수 있다.
📄참고자료
[인프런] c#과 유니티로 만드는 MMORPG 게임 개발 시리즈_3. 유니티 엔진
Unity Documents_UnityEngine.EventSystems
Unity Documents_IBeginDragHandler
Unity Documents_IDragHandler