강의, 책/[Unity] C#과 유니티로 만드는 MMORPG 게임 개발 시리즈

Section 7. UI - UI 자동화(이벤트)

hye3193 2024. 1. 26. 20:37

Assets > Scripts > UI > UI_EventHandler.cs

(EventSystem이 클릭을 감지하여 이벤트를 뿌려주면 UI에서 캐치해서 콜백 함수를 날려주는 역할, 드래그 이벤트를 감지할 오브젝트에 부착해주면 된다)

public class UI_EventHandler : MonoBehaviour, IPointerClickHandler, IDragHandler
{
    public Action<PointerEventData> OnClickHandler = null;
    public Action<PointerEventData> OnDragHandler = null;
    
    public void OnPointerClick(PointerEventData eventData)
    {
        if (OnClickHandler != null)
            OnClickHandler.Invoke(eventData);
    }
    
    public void OnDrag(PointerEventData eventData)
    {
        if (OnDragHandler != null)
            OnDragHandler.Invoke(eventData);
    }
}

 

Assets > Scripts > Utils > Define.cs 스크립트에 UIEvent를 추가해준다

public class Define
{
    public enum UIEvent
    {
        Click,
        Drag
    }
}

 

그리고 Assets > Scripts > Utils > Util.cs 스크립트에서 component를 받아오고, 없을 경우 추가시켜주는 함수를 만든다

public static T GetOrAddComponent<T>(GameObject go) where T : UnityEngine.Component
{
    T component = go.GetComponent<T>();
    if (component == null)
        component = go.AddComponent<T>();
    return component;
}

 

만든 함수를 이용해서 Assets > Scripts > UI > UI_Base.cs 스크립트에 AddUIEvent 함수를 추가해준다

public static void AddUIEvent(GameObject go, Action<PointerEventData> action, Define.UIEvent type = Define.UIEvent.Click)
{
    UI_EventHandler evt = Util.GetOrAddComopnent<UI_EventHandler>(go);
    
    switch (type)
    {
        case Define.UIEvent.Click:
            evt.OnClickHandler -= action;
            evt.OnClickHandler += action;
            break;
        case Define.UIEvent.Drag:
            evt.OnDragHandler -= action;
            evt.OnDragHandler += action;
            break;
    }
}

* 추후 코드 정리할 때 이름을 AddUIEvent -> BindEvent로 변경한다

 

그리고 Assets > Scripts > UI > UI_Button.cs(ui 캔버스에 부착하던 스크립트)에서 AddUIEvent 함수를 호출하여 연결해준다

GameObject go = GetImage((int)Images.ItemIcon).gameObject;
AddUIEvent(go, (PointerEventData data) => { go.transform.position = data.position; }, Define.UIEvent.Drag);

드래그할 경우 물체가 커서를 따라 드래그하게 되는 기능, action은 람다 함수로 넣어주었다

 

+ extension method

Assets > Scripts > Utils > Extension.cs 스크립트 내에 작성한다

* static 선언 필요, MonoBehaviour 제거

public static class Extension
{
    public static void AddUIEvent(this GameObject go, Action<PointerEventData> action, Define.UIEvent type = Define.UIEvent.Click)
    {
        UI_Base.AddUIEvent(go, action, type);
    }
}

그리고 UI_Buttons 스크립트에서 아래와 같이 선언해서 UIEvent를 추가해줄 수 있다

Bind<Button>(typeof(Buttons));
GetButton((int)Buttons.PointButton).gameObject.AddUIEvent(OnButtonClicked);

public void OnButtonClicked(PointerEventData data)
{
    _score++;
    GetText((int)Texts.ScoreText).text = $"점수 : {_score}";
}

* 기본 UIEvent type이 Click이기 때문에 함수 선언부에서 action만 명시해두었다