UnityEvent
https://docs.unity3d.com/kr/530/ScriptReference/Events.UnityEvent.html
유니티 Documents에는 위와 같이 api를 제공하고 있습니다만...
사실 필자는 API문서를 봐도 별로 좋아하지 않습니다. 이게 언제 어떻게 사용되는지 알 수가 없어서 아 그냥 이런게 있구나 그리고 용도를 알고나서는 도움이 되긴하는데 뭔가 찾는 단어 없이 사전을 찾아 보는 느낌이라고 해야할까요.
어쨌든 UnityEvent는 Delegate와 많이 엮이어져서 소개되어지곤 하는데요.
우선 어떠한 문제를 해결하고자 한건지 이야기 해봅니다.
상황) 플레이어가 사망시 플레이어 오브젝트는 사망하는 애니메이션이라던가 사라진다던가 그리고 UI에서 Game Over라는 문구도 띄울 것이고 게임이 새로 시작되기도 할 것입니다.
만약 위와 같은 상황이라면 플레이어의 사망처리 메서드 호출 -> UI에서 Game Over라는 텍스트를 띄우는 메서드 호출 -> 게임을 다시 시작하는 메서드 호출
총 3가지의 메서드를 호출 해야합니다.
이 모든 메서드가 한 스크립트에서 제어를 한다면 조금은 덜 필요하실 수 있겠습니다만 실제로 그런식으로 구조를 짜는 일이 드물고 각각 용도에 맞게 분리되어서 관리를 합니다.
이렇게 되었을 때에
위와 같이 각 메서드를 갖고 있는 스크립트를 등록하고 변수에 할당하고 각각의 스크립트를 호출하게 됩니다.
구현이야 되겠지요.
하지만 앞으로 사망시 이벤트가 계속 추가가 된다면 어떨까요? 죽었을때 효과음이 어떤게 추가됐으면 좋겠고 업적 달성이라는 게 생겼으면 좋겠고 다시 하기는 3번까지만 제한됐으면 좋겠고...
구현이야 되겠지만 위와 같은 방식이라면 사망시 이벤트가 추가 될때마다 저 Dead()라는 메서드에 이벤트들을 등록해야하고 새로운 스크립트의 이벤트라면 다시 스크립트를 물려야하고 굉장히 번거롭게 됩니다.
즉, 모든 계획은 처음에 완벽하지 못하기 때문에 후에 수정에 용이하게 짜여져야한다는 것이 핵심입니다.
그래서 우리는 이벤트가 발생하면 각 스크립트에서 아 플레이어의 상태가 이렇대 라고 알고 알아서 관련된 이벤트들을
호출 시키고 싶습니다. 그 편이 관리하기도 편하고 수정하기도 편할거라 생각합니다.
자, 알아봅시다. Unity Event는
각 다른 클래스에서 이벤트에 등록하고 그 이벤트 상태가 되었을시에 등록했던 모든 이벤트들이 상태를 받아서 발동하는 방식입니다.
사용해봅시다.
우선 스크립트 내부에서 using UnityEngine.Events를 추가해줍시다.
그러면 UnityEvent 변수를 선언할 수 있게 되는데
하나 선언해주고 캐릭터가 죽었을때 이 이벤트를 발동(Invoke()) 시켜봅시다.
추가하면 이렇게 되겠지요.
트리거에 통과했을시에 Dead()라는 메서드가 호출이되고, UnityEvent인 onPlayerDead 이벤트를 발동시키는 내용입니다.
그리고 앞서 만들었던 코드처럼 캐릭터가 죽었을 시에 다양한 이벤트들을 같이 호출하고 싶습니다.
아마 버튼 이벤트 추가하는 방법을 아신다면 비슷한 방식입니다.
위 public UnityEvent onPlayerDead를 선언해주었기 때문에 해당 스크립트를 물고 있는 오브젝트에서
이렇게 이벤트 리스트를 받을 공간을 마련해줍니다. 그리고 이벤트들을 추가시키려면 오른쪽 하단에 + 버튼을 누르고 하나씩 추가해주면 됩니다.
그리고 보시는 바와 같이 이벤트들을 등록해주면됩니다. 버튼 이벤트 등록할 때 처럼! 스크립트상에서는 onPlayerDead+=해당이벤트 메서드;
해주면 됩니다.
위와 같이 만들게 되면 각 클래스와의 의존도를 낮추면서 더 깔끔하고 코드줄이 줄어들기 때문에 유지 보수하는 측면에서도 유리합니다.
UnityEvent는 C#이 아닌 Unity제공 클래스입니다. 그리고 이것에 대한 근간이되는 C#의 Delegate(대리자) Event가 있습니다.
'Unity > C# Script' 카테고리의 다른 글
GameObject의 각속도 구하기 (6) | 2020.08.05 |
---|---|
유니티 C# Script에서 Null Conditional Operator (0) | 2020.08.04 |
C#의 Static (0) | 2018.05.16 |