이벤트하면
뭐 경험치 2배, 선물 주는 것 생각이 나는
여기선 그건 아니고
정말 이벤트다.
사건이라고... 해석하기보다 그냥 Event로 받아들이자.
알아보자
정의해보자
어떤 이벤트가 일어났으면 설정해놓은 메서드를 불러와서 실행시킨다.
delegate에 메서드를 담아서 실행시키는 것과 비슷한 원리다.
다만 Event는 static으로 선언되어 객체없이도 어디서나 접근할 수 있게해놓는 것이다.
그렇게 이용한다고 한다.
public delegate void ClickAction();
public static event ClickAction OnClicked;
이런 식으로 선언한다.
delegate으로 먼저 선언해준다.
그 후 event 키워드를 사용하여 메서드를 써준다.
** static으로 설정하지 않아도 오류가 생기지는 않는다.
??? 아니 근데 그냥 public으로 delegate 쓰면 똑같은 거 아니여???
맞잖아. 똑같이 작동도 하는데??
라고 생각할 수 있다.
Event 는 delegate의 일종인 것 맞다.
하지만 특수화된 delegate라고 보면 된다.
Event는 보안성이 보장된다고 해야 할까..?
그냥 delegate로 쓰면 보장이 되지는 않는데??
이게 무슨 말이냐하면
Event는 다른 클래스와 그냥 참조하거나 말거나 관계만 유지한다.
즉, 외부에서 직접 사용이 불가능하다.
public으로 선언되었어도 그 해당 이벤트가 선언된 클래스 외부에서는 직접 호출이 불가능하다.
-> 이것이 안정성을 추구하는 방식이라고 한다.
하지만 Public으로 delegate를 선언하면 외부에서 호출이 가능하다.
예시로는
EventManager
using UnityEngine;
using System.Collections;
public class EventManager : MonoBehaviour
{
public delegate void ClickAction();
public static event ClickAction OnClicked;
void OnGUI()
{
if(GUI.Button(new Rect(Screen.width / 2 - 50, 5, 100, 30), "Click"))
{
if(OnClicked != null)
OnClicked();
}
}
}
먼저 delegate를 선언한 후
onClicked를 event로 선언했다.
스크린에 버튼을 만들고 버튼이 클릭되면 Onclicked 메서드가 실행될 것이다.
만약 그냥 실행하면 OnClicked()에 대한 참조메서드가 없으므로 오류가 생긴다.
if(OnClicked != null)
그래서 이 부분이 필요한 것이다.
아래 2가지 스크립트로 Onclicked를 이용해보자
TeleportScript
using UnityEngine;
using System.Collections;
public class TeleportScript : MonoBehaviour
{
void OnEnable()
{
EventManager.OnClicked += Teleport;
}
void OnDisable()
{
EventManager.OnClicked -= Teleport;
}
void Teleport()
{
Vector3 pos = transform.position;
pos.y = Random.Range(1.0f, 3.0f);
transform.position = pos;
}
}
OnEnable은 내장 함수로 오브젝트가 활성화되면 실행된다.
OnDisable은 내장함수로 오브젝트가 비활성화되거나 파괴될 때 실행된다.
** += 또는 -= 연산자로 참조하는 메서드들을 관리할 수 있다.
즉, 활성화된 오브젝트에 대해서 이벤트가 일어나면 Teleport 메서드도 실행될 것이라는 것이다.
또한 비활성화 되면 Teleport 메서드는 이벤트가 일어나도 실행되지 않을 것이다.
TurnColorScript
using UnityEngine;
using System.Collections;
public class TurnColorScript : MonoBehaviour
{
void OnEnable()
{
EventManager.OnClicked += TurnColor;
}
void OnDisable()
{
EventManager.OnClicked -= TurnColor;
}
void TurnColor()
{
Color col = new Color(Random.value, Random.value, Random.value);
renderer.material.color = col;
}
}
얘도 마찬가지다.
그리고 이벤트를 선언할 때는 초기화하는 것을 잊지 말자.
만약 이런 식으로 이벤트 관리가 되지 않는다면
메모리 낭비와 에러가 발생할 수 있다.
그래서
메서드를 참조하게 만들 때는 참조를 끊는 경우도 위와 같이 해놓는게 건강에 좋다.
이벤트 솔직히 많이 써봐야 감이 올 것 같다.
아직 안 오는 것을 보니 멀었다.
참고링크
'Game Development, 게임개발 > 개발' 카테고리의 다른 글
Handling Event, 이벤트 활용하기 - 2 [Unity] (0) | 2021.04.03 |
---|---|
Handling Event, 이벤트 활용하기 [Unity] (0) | 2021.04.03 |
어트리뷰트, Attributes [Unity] (0) | 2021.04.02 |
델리게이트, Delegates [Unity] (0) | 2021.04.02 |
Coroutine,코루틴(IEnumerator, StartCoroutine, yield 등 )에 대한 모든 것 [Unity] (0) | 2021.03.30 |