본문 바로가기

Unity

[Unity3D] [C#]Delegate 응용, 쉽게 사용 좀 해보자

1. 서론

뭐 대리인이네 콜백이네 체인이네 하는 '수학의 정석' 제일 앞장 집합 같은 소리는 집어치우고

딱 한마디로 코드 덩어리(함수)를 값 대신 사용한다고 보면 쉽다.

 

c++ 에선 함수 포인터와 비슷하다고 볼 수도 있겠다.

이 둘은 비슷하지만 분명히 다른 점이 있을 거라 본다. 아직 필자는 자세히 공부를 안 해봐서 모르겠다.

곧 알게 되면 다시 기록하도록 하겠다.

 

2. 본론

필자는 버튼을 눌렀을 때 물건을 샀으면 좋겠는 기능이 필요했다.

헌데, 여러 가지 조건들이 추가되니 너무 코드가 보기도 싫고 이곳저곳의 객체를 가져와야 하는 상황이 생겨버렸다.

그래서 델리게이트를 사용해보고자 했다.

//GlobalEvent.cpp
using Global;
using System;
using UnityEngine;

namespace GlobalEvent
{
    public delegate void Del_TowerSet(tTowerInfo _info);
}

 GlobalEvent로 전역에 델리게이트를 선언하였다. Delegate는 굳이 Class 안이 아니더라도 사용할 수 있다.

 tTowerInfo 타워의 정보를 받는 인자를 가진 함수 주소를 담을 수 있는 공간이 생겼다고 볼 수 있다.

 

//WaitField.cpp
public class WaitField: TileController
{
 
    private void Start()
    {
        TowerSetEvent.BuyTowerEvent += WaitField_BuyTowerEvent;
    }

    private void WaitField_BuyTowerEvent(tTowerInfo _info)
    {
        Debug.Log("asd");
    }
}

 Start() 안에 += 등으로 이벤트를 추가할 수 있다. 이것을 체인이라고 부르는 것이다. 델리게이트 체인

 한 가지 이벤트가 아닌 여러 이벤트를 등록할 수 있어 체인이라 부르는 것이다. 

 여기서 중요한 점은 인자와 리턴할 타입을 맞춰주어야 한다.

 

//TileController.cpp
static class TowerSetEvent
{
    public static event Del_TowerSet BuyTowerEvent;
    public static void Action(tTowerInfo _info)
    {
        BuyTowerEvent(_info);
    }
}

 Static class 안에 Static이벤트로 등록 해 두었다. 어차피 지존 많이 호출될 이벤트이기 때문에 Static에 이벤트 등록을 해두기도 하였고, 여러 클래스에서 저 이벤트에 상점구매 버튼을 눌렀을 때 호출될 함수들을 등록하기 위해 전역으로 빼두었다.

 

//CButton.cpp
public void BtnAction()
{
	if (m_iCost <= Player.Instance.GetGold())
	{
		TowerSetEvent.Action(m_tTowerInfo);
	}
}

 마지막은 BtnAction은 상점 버튼을 눌렀을 때 Action 펑크를 통해 이벤트를 호출하도록 하였다.

 그럼 등록된 이벤트들이 촤르르륵 불리겠지.

 

3. 결론

아직 테스트는 안 해봤는데, 아마 될 거다.

문제가 있을법한 일은 static으로 리턴 타입과 인자만 같으면 이벤트에 다 등록되는데 이런 부분들을 좀 명시적으로

다른 개발자들도 헷갈리지 않게 사용할 수 있도록 하는 것과, 이벤트를 한눈에 보고 파악할 공간을 분할해야 한다는 점이겠다. 아무래도 저러면 디버깅 하기도 이벤트가 몇 개 달렸는 지도 파악하기 귀찮고 힘들 거다.

 

조만간 좋은 아이디어로 변경된다면 다시 글을 쓰도록 하겠다.