OnEnable에서 구독하기
Coddy Unity 여정의 Unity 게임 아키텍처 섹션에 포함된 레슨. 50개 중 11번째.
리스너가 파괴되어도 이벤트에서 저절로 제거되지는 않습니다. 이벤트는 여전히 해당 메서드를 보유하고 있으며, 다음 Invoke가 파괴된 컴포넌트에서 이 메서드를 호출합니다. 이 메서드에서 transform을 처음 사용하면 MissingReferenceException이 발생하고, 예외가 발생하면 Invoke가 종료되므로 그 뒤에 있는 리스너도 건너뛰게 됩니다. 따라서 모든 +=에는 -=가 필요하며, 이를 위한 Unity의 메서드 쌍은 OnEnable과 OnDisable입니다:
public class Guard : MonoBehaviour
{
public Alarm alarm;
void OnEnable()
{
alarm.OnTriggered += RunTo;
}
void OnDisable()
{
alarm.OnTriggered -= RunTo;
}
void RunTo(Vector3 spot)
{
transform.LookAt(spot);
}
}Unity는 SetActive(false)로 오브젝트가 꺼질 때, 스크립트가 비활성화될 때, 그리고 오브젝트가 파괴될 때 OnDestroy보다 먼저 OnDisable을 호출합니다. 오브젝트가 다시 활성화될 때마다 OnEnable이 실행됩니다. 이 메서드 쌍을 사용하면 가드는 활성화되어 있는 동안에만 정확히 이벤트를 수신합니다. 파괴된 가드는 이벤트에서 제거되고, 컷신을 위해 꺼진 가드는 알람을 무시하며, 다시 켜지면 이벤트를 다시 수신합니다.
다른 두 가지 조합은 잘못 동작합니다. Start에서 +=를 하고 OnDisable에서 -=를 하면, 껐다가 다시 켠 가드는 Start가 한 번만 실행되므로 더 이상 이벤트를 수신하지 않습니다. OnEnable에서 +=를 하고 -=를 하지 않으면, 활성화될 때마다 RunTo가 다시 추가되어 알람 한 번에 두 번 호출됩니다. 구독되지 않은 메서드를 제거해도 아무 일도 일어나지 않으므로 OnDisable에서 -=를 사용할 때는 확인 절차가 필요하지 않습니다.
챌린지
쉬움Bell.cs, 준비 완료), 종의 이벤트 OnRing가 마을 사람들에게 이를 알립니다. 마을 사람은 종이 울릴 때마다 깡충 뛰고 ringsToLeave번 울린 뒤 집으로 돌아갑니다. Hop은 마을 사람을 파괴합니다. Ana는 2번 울린 뒤 집으로 돌아갑니다. 세 번째로 종을 울리면 Console에 MissingReferenceException이 표시됩니다.
Villager.cs를 수정해 마을 사람이 활성화되어 있는 동안에만 종 이벤트를 듣도록 하세요.
- 마을 사람이 활성화될 때마다
Hop을 종의 이벤트에 구독하고, 마을 사람이 비활성화되거나 파괴될 때 구독을 해제하세요.Hop과Update는 그대로 두세요. SetActive(false)로 비활성화된 마을 사람은 깡충 뛰지 않습니다. 다시 활성화하면 종이 울릴 때마다 한 번씩 깡충 뜁니다.
플레이를 누르고 종을 네 번 울린 다음 Console을 확인하고, 확인을 누르세요.
직접 해보기
using UnityEngine;
public class Villager : MonoBehaviour
{
public Bell bell;
public int ringsToLeave = 3;
public int hops;
void Start()
{
bell.OnRing += Hop;
}
void Update()
{
// 한 번 뛰어오른 후 다시 땅으로 내려오기
Vector3 p = transform.position;
transform.position = new Vector3(p.x, Mathf.MoveTowards(p.y, 0.5f, 4f * Time.deltaTime), p.z);
}
void Hop(int ring)
{
hops++;
transform.position += Vector3.up * 0.8f;
if (hops == ringsToLeave)
{
Debug.Log(name + " goes home");
Destroy(gameObject);
}
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.