
UnityEventUnityEvent는 델리게이트와 비슷한 역할로 Unity에서 편하게 사용할 수 있도록 고안된 기능으로, 직렬화가 가능하여 인스펙터 창에서 다른 컴포넌트의 메서드를 등록하고 실행할 수 있게 한다.
이는 디자이너와 개발자 간의 협업을 더 쉽게 만들어주는 시스템으로써의 장점을 갖는다.
public class UnityEventTest : MonoBehaviour
{
public UnityEvent myEvent;
private void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
myEvent?.Invoke(); // 등록된 메서드(Test) 호출
}
}
}
public class Tester : MonoBehaviour
{
public void Test()
{
Debug.Log("인스펙터로 구독 가능");
}
}
위와 같은 코드를 작성하면 인스펙터 창에서 myEvent에 Tester와 Test()를 등록하여 간편하게 사용할 수 있다.
MethodInvoke() // 구독 함수 실행
AddListener() // 함수 구독
RemoveListener() // 구독 취소
public class UnityEventTest : MonoBehaviour
{
public UnityEvent myEvent;
public void Awake()
{
// C# event와 달리 해당 문법은 지원하지 않는다.
// myEvent += Test1;
myEvent.AddListener(Test1);
myEvent.RemoveListener(Test1);
}
private void Update()
{
myEvent?.Invoke();
}
private void Test1(){}
ParameterUnityEvent도 델리게이트와 마찬가지로 소스코드 내에서는 매개변수가 동일해야 AddListener로 구독하는 것이 가능하다.
public class UnityEventTest : MonoBehaviour
{
public UnityEvent<int> myEvent;
public void Awake()
{
myEvent.AddListener(Test1); // 가능
myEvent.AddListener(Test2); // 불가능
}
public void Test1(int n) {}
public void Test2() {}
하지만 인스펙터에서는 매개변수가 다른 함수도 이벤트에 등록할 수 있으며, 등록을 할 때 매개변수에 어떤 값을 넣을지 지정할 수 있다. 반대로 매개변수가 필요한 이벤트여도 매개변수가 없는 함수를 등록하여 사용하는 것도 가능하다.
이는 Unity 인스펙터에서 UnityEvent에 메서드를 연결할 때 C#의 Reflection을 사용하기 때문이다. Unity는 런타임에 메서드 정보를 조회하고 인스펙터에서 지정한 값으로 파라미터를 자동으로 넘겨줄 수 있어, 코드 상에서는 시그니처가 일치해야하지만 인스펙터에서는 더 유연하게 사용 가능하다.
public class UnityEventTest : MonoBehaviour
{
public UnityEvent myEvent;
public UnityEvent<float> myFloatEvent;
private void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
myEvent?.Invoke(); // Test1 구독 및 실행 가능
myFloatEvent?.Invoke(1.5f); // Test2 구독 및 실행 가능
}
}
}
public class Tester : MonoBehaviour
{
public void Test1(int n)
{
Debug.Log("인스펙터로 구독 가능");
}
public void Test2()
{
Debug.Log("인스펙터로 구독 가능");
}
}
UnityAction유니티 초창기 여러 언어를 지원할 때 일부 언어의 경우 델리게이트 문법이 존재하지않아 과거 UnityAction이라는 기능이 만들어졌다.
UnityEvent 또한 내부적으로는 UnityAction으로 구현되어있으나, C#에서의 Action과 동일한 기능을 가지고 있기에 현재는 대부분의 경우 Action을 사용하거나 UnityEvent를 직접 사용하는 편이다.
public class UnityActionTest : MonoBehaviour
{
public event UnityAction OnDied;
public event Action myDel;
}