Quick Reference
매 frame 작업이 없으면 Update 계열 메시지를 정의하지 않고, 상태 관측은 Update·물리는 FixedUpdate·후처리는 LateUpdate·변경 통지는 event로 둡니다.
- 기준 버전은 Unity 6.5 (6000.5)입니다. 매 frame 일이 없으면
Update,FixedUpdate,LateUpdate를 정의하지 않습니다. Unity는 정의된 메시지만 lifecycle 호출 대상으로 관리합니다. - 매 frame 상태를 관측해야 하면 Update, 물리 step이면 FixedUpdate, 다른 이동 뒤 보정이면 LateUpdate를 씁니다. 값이 바뀌는 순간을 이미 알 수 있으면 event/callback이 더 직접적입니다.
- event는 무료 Update가 아닙니다. 높은 빈도의 발행, 중복 구독, 해제 누락, 실행 순서 의존이 있으면 polling보다 더 복잡하거나 비쌀 수 있습니다.
메시지 선택
| 필요한 일 | 맞는 연결 지점 | 피할 선택 |
|---|---|---|
| 매 frame 조준·추적 | Update | 여러 event를 억지로 조합 |
| 물리 force·Rigidbody 이동 | FixedUpdate | Update에서 물리 주기 가정 |
| 카메라 follow 최종 보정 | LateUpdate | 대상 이동 전에 위치 확정 |
| HP/인벤토리 값 변경 반영 | event/callback | 매 frame UI polling |
| 순차 대기 후 다음 단계 | coroutine | 빈 Update 상태 머신 |
- 빈 메시지 하나의 비용은 보통 작습니다. 하지만 수천 개의 Behaviour에 쌓이면 native-to-managed callback과 리스트 순회가 누적될 수 있습니다. Profiler에서 실제
BehaviourUpdate비용과 대상 수를 확인한 뒤 정리합니다. OnEnable/OnDisable은 event 구독을 수명주기와 맞추는 대표 위치입니다. listener가 disable된 UI나 scene-unload object를 계속 잡고 있으면 memory leak과 중복 callback으로 이어질 수 있습니다.- coroutine도 활성 GameObject가 비활성화되거나 destroy될 때의 중단,
timeScale영향, 재시작 정책을 따로 설계해야 합니다. Update를 없앴다는 사실만으로 lifecycle 문제가 사라지지 않습니다.
event 연결 예제
csharp
using System;
using UnityEngine;
public sealed class Health : MonoBehaviour
{
public event Action<int> Changed;
public int Current { get; private set; }
public void SetCurrent(int value)
{
Current = value;
Changed?.Invoke(Current);
}
}
public sealed class HealthBar : MonoBehaviour
{
[SerializeField] private Health health;
private void OnEnable()
{
health.Changed += Refresh;
Refresh(health.Current);
}
private void OnDisable() => health.Changed -= Refresh;
private void Refresh(int currentHp)
{
// Slider, Image fillAmount, TextMeshPro 등을 실제 값으로 갱신합니다.
}
}- event source가 여러 번 같은 값을 보낼 수 있는지, listener가 enable될 때 즉시 현재 상태를 한 번 그려야 하는지까지 정합니다. 구독만 하고 첫 화면을 그리지 않으면 초기 UI가 비어 보일 수 있습니다.
FixedUpdate를 비우고 남겨 두지 마세요. 물리와 관계없는 작업을 여기로 옮겨 frame rate 문제를 “고치는” 것은 호출 빈도와 input timing을 더 예측하기 어렵게 합니다.- 대상이 대량이고 각자 저빈도 tick이 필요하면 Update Manager를 고려할 수 있지만, manager 등록 해제와 예외 정책을 함께 가져가야 합니다.
자주 틀리는 부분
event 구독 해제는 선택이 아닙니다. scene object가 오래 사는 singleton의 event에 남아 있으면 destroy된 listener가 계속 호출되거나 참조가 유지될 수 있습니다. 수명주기에 맞는 unsubscribe와 초기 상태 갱신을 한 쌍으로 작성하세요.
템플릿의 빈 Update를 지우는 일과 polling을 event로 바꾸는 일은 다릅니다. 전자는 불필요한 lifecycle callback을 제거하는 단순 정리이고, 후자는 데이터 소유자와 ordering contract를 바꾸는 설계 변경입니다. 후자는 Profiler와 테스트로 행동이 유지되는지 확인해야 합니다.
참고 링크
2 sources