초고교급 희망

[Unity] UI 자동화 (2) 본문

Game/Unity

[Unity] UI 자동화 (2)

연모링 2023. 7. 20. 17:55
728x90

https://ymthebest.tistory.com/38

 

[Unity] UI 자동화 (1)

서론... [SerializeField] TMP_Text _text; ↑ 위와 같이 유니티 툴에서 직접 해당하는 오브젝트들을 바인딩하게 되면 번거롭다. 툴에서 하지 않고 코드를 통해 바인딩 하는 UI 자동화에 대해 배워보겠습니

ymthebest.tistory.com

저번 게시글에 이어서 UI 이벤트를 알아보겠습니다.

 

UI_EventHandler.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class UI_EventHandler : MonoBehaviour, IBeginDragHandler, IDragHandler
{
    public Action<PointerEventData> OnBeginDragHandler = null;
    public Action<PointerEventData> OnDragHandler = null;

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (OnBeginDragHandler != null)
            OnBeginDragHandler.Invoke(eventData);
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (OnDragHandler != null)
            OnDragHandler.Invoke(eventData);
    }
}

IBeginDragHandler, IDragHandler등을 상속받아서 오버라이딩 했습니다.

이제 해당 이벤트가 실행될 때 저 이벤트 함수가 실행됩니다.

 

UI_Button.cs

Bind<Image>(typeof(Images));
GameObject go = GetImage((int)Images.ItemIcon).gameObject;
UI_EventHandler evt = go.GetComponent<UI_EventHandler>();
evt.OnDragHandler += ((PointerEventData data) => { evt.gameObject.transform.position = data.position; });

저번시간에 구현했던걸로 바인딩부터 해줍니다.

그리고 이벤트를 람다식으로 연결해줬습니다.

 

근데 저 이벤트를 하나하나 추가해주는 부분을 또 간단하게 고쳐보겠습니다.

UI_Base.cs

이전 게시글에 나오는 내용이지만...

UI_Base는 말 그대로 베이스 입니다.

UI_Button은 UI_Base를 상속합니다.

public static void AddUIEvent(GameObject go, Action<PointerEventData> action, Define.UIEvent type = Define.UIEvent.Click)
    {
        UI_EventHandler evt = Util.GetOrAddComponent<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;

        }
        evt.OnDragHandler += ((PointerEventData data) => { evt.gameObject.transform.position = data.position; });
    }

Define.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

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

 

Util.cs

    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;
    }

게임 오브젝트에 해당 컴포넌트가 있으면 가져오고,

없다면 붙여서 가져오는 함수입니다.

이 부분도 자주 사용되기 때문에 Util에 만들어줍니다.

 

그래서 이제 이렇게 사용하면 됩니다.

UI_Button.cs

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

짜잔~

근데 이제 여기서 더 간단하게 만들어보겠습니다.

저기 gameObject.AddUIEvent 이런식으로 바로 연결해서 한 줄 짜리로 만들 수 있습니다.

C#에 있는  extension(확장명 메서드)를 사용하면 됩니다.

 

Extension.cs

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

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_Button.cs

GetButton((int)Buttons.PointButton).gameObject.AddUIEvent(OnButtonClicked);

이제 이렇게 간단하게 클릭 이벤트를 연결할 수 있게 됐습니다.

 

private void Start()
{
    Bind<Button>(typeof(Buttons));
    Bind<TMP_Text>(typeof(Texts));
    GetButton((int)Buttons.PointButton).gameObject.AddUIEvent(OnButtonClicked);
}

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

지금까지 모은걸 총 집합한 예시입니다

먼저 바인드함수로 버튼과 텍스트들을 모두 자동 바인딩 해줍니다.

그리고 원하는 버튼에 클릭 이벤트를 붙입니다.

그 때 실행되는 OnButtonClicked 함수에서 text를 바꿔줍니다.

 

 

<출처>

인프런 루키스 선생님의 [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] 를 듣고 정리한 내용입니다.^^

728x90