Event Driven Programming을 지원하는 경우가 많다.Event Driven Programming은 Pub-Sub Pattern과 유사하게 실현된다.Class에 어떤 method를 실행시킬 것인지를 등록, 삭제하는 것을 의미한다.eventhttps://learn.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/event
+=, -=가 기본적으로 override 되어있고, 사용방법은 직관적으로 구독, 취소 할 수 있다.public class SampleEventArgs
{
public SampleEventArgs(string text) { Text = text; }
public string Text { get; } // readonly
}
public class Publisher
{
// Declare the delegate (if using non-generic pattern).
public delegate void SampleEventHandler(object sender, SampleEventArgs e);
// Declare the event.
public event SampleEventHandler SampleEvent;
// Wrap the event in a protected virtual method
// to enable derived classes to raise the event.
protected virtual void RaiseSampleEvent()
{
// Raise the event in a thread-safe manner using the ?. operator.
SampleEvent?.Invoke(this, new SampleEventArgs("Hello"));
}
}
UnityEventclass in UnityEngine.Events
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Events.UnityEvent.html
이 키워드는 Class로 취급된다.
과거의 공식적인 설명에 근거한다면, UnityEvent는 추가 프로그래밍 및 스크립트 설정 없이도 사용자 기반 콜백이 편집 시간부터 런타임까지 유지되도록 하는 방법이라고 설명한다.
이 말은 플레이모드에 진입해도 중간중간 컴파일이 다시되어도 문제없이 다시 실행된다는 것이다.
이는 Inspector에서 삭제되지 않음을 의미한다.
"추가 프로그래밍 없이": 코드를 수정하지 않고 Inspector(에디터) 상에서 드래그 앤 드롭으로 이벤트를 연결할 수 있다는 뜻이다. (협업에 유리)
"편집 시간부터 런타임까지 유지": 연결 정보를 직렬화(Serialization)해서 저장한다는 의미다.
사용법은 살짝 다르다. AddListener와 RemoveListener로 이벤트를 추가/제거해야 한다.
호출은 Invoke로 가능하다. Generic을 사용하면 인자도 넣을 수 있다.
Trade-off가 좀 있다.
편리한 만큼 순수 C# event에 비해 성능 오버헤드가 있고, 호출 시 가비지(Garbage)가 발생할 수 있다.
따라서 매 프레임 호출되는 Update 문보다는, UI 클릭이나 게임 로직의 상태 변화 등 빈도가 적은 이벤트에 사용하는 것이 적합하다.
예시코드는 아래와 같다.
using UnityEngine;
using UnityEngine.Events;
public class ExampleClass : MonoBehaviour
{
UnityEvent m_MyEvent;
void Start()
{
if (m_MyEvent == null)
m_MyEvent = new UnityEvent();
m_MyEvent.AddListener(DoSomething);
}
void OnDestroy()
{
m_MyEvent.RemoveListener(DoSomething);
}
void Update()
{
if (Input.anyKeyDown && m_MyEvent != null)
{
m_MyEvent.Invoke();
}
}
void DoSomething()
{
Debug.Log("Callback called");
}
}