0411 - Unity 부트캠프[5일차] Unity Script Livecycle

Hyeon O·2025년 4월 11일

Unity_BootCamp 1주차

목록 보기
5/5
post-thumbnail

Unity의 실행 사이클에 대하여

그동안 Unty를 다루면서,

가볍게 짚고 넘어간 실행 사이클에 대해서 분석과 정리를 해보자.

Unity 문서를 참고할 것이며 추가적인 내용은 웹에서 더 찾아서 정리해 볼 것이다.

Unity 실행 사이클 문서 링크

실행 사이클이란?

Unity에서는 MonoBehaviour를 상속한 스크립트 컴포넌트가 특정 이벤트 함수를 통해 자동으로 호출된다.

이 함수들은 Unity 엔진이 오브젝트의 상태 변화나 프레임에 따라 호출하는 일종의 콜백 메서드다.

스크립트를 새로 생성하면 바로 보이는 Start()와 Update() 함수가 이에 해당한다.

하지만 그 외에도 무척 많은데,

이 기회에 한 번 다 짚고 넘어 가보자

스크립트 라이브사이클 플로우 차트

아래는 Unity 메뉴얼에서 제공하는 스크립트 라이브사이클 플로우 차트다.

위 플로우에 따라서 하나 하나 분석 및 정리 해보자.

Initialization(초기화 단계) : 씬이 시작할 때 한번 → (Editor)

🔹Awake()

  • 오브젝트가 씬에 로드되거나 인스턴스화될 때 가장 먼저 호출됨
  • 의존성 주입, 데이터 초기화, 싱글톤 설정 등에 사용
  • 한 번만 호출됨
  • 비활성 상태인 경우 활성화 될 때 까지 호출되지 않음

🔹 OnEnable()

  • 오브젝트가 활성화(Enable = true) 될 때 호출
  • 즉, 오브젝트 활성화 직후 호출
  • Awake보다 나중에 실행되며, 활성화될 때마다 반복 호출됨

Editor → (Initialization2)

🔹 Reset()

  • 컴포넌트를 처음 추가했을 떄 호출
  • 에디터 상에서 개발자가 설정하기 쉽게 하기 위해 제공되는 함수
  • 런타임 초기화가 아닌, 에디터 상태에서의 자동 초기화

Initialization2(초기화 단계) → (Physics)

🔹start()

  • 첫 번째 프레임 업데이트 전에 한 번만 실행
  • 다른 스크립트나 컴포넌트가 준비된 후 실행되기 때문에, 초기화에 가장 안전하다.

Physics(물리 연산 단계) → Input event 또는 Physics(재귀)

🔹 FixedUpdate()

  • 일정한 시간 간격으로 호출(기본 0.02s)
    • TIme.deltaTime만큼 값을 곱할 필요없음
    • 프레임 속도와 관계없이 호출되기 때문
  • 프레임 속도가 낮은 경우 프레임당 여러 번 호출될 수 있다.
  • 프레임 속도가 높은 경우 프레임 사이에 호출되지 않을 수 있다.
  • 모든 물리 계산 및 업데이트는 이 함수 후 즉시 발생한다.

Physics(물리 연산 단계) - nternal Animation Update : 물리 전 애니메이션 갱신

단계설명
State Machine updateAnimator Controller의 현재 상태(State) 갱신
OnStateMachineEnter/Exit()상태 진입/이탈 시 콜백
ProcessGraph모든 애니메이션 그래프를 평가, 여기에는 평가할 모든 애니메이션 클립에 대한 샘플링과 루트 모션 계산이 포함
Fire animation events애니메이션에 지정된 이벤트 호출 (예: AnimationEvent)
StateMachineBehaviour callbacks애니메이션 스테이트에 붙은 사용자 정의 스크립트 실행, 이 콜백을 정의하는StateMachineBehaviour 이 포함된 각 활성 상태에 대해 호출
OnAnimatorMove()업데이트 프레임마다 루트 모션을 수정할 수 있도록 각 Animator 컴포넌트에 대해 한 번 호출, Root Motion을 사용하는 경우, 움직임 벡터를 가져오는 곳

이 시점까지는 애니메이션 데이터 기반으로 움식임 계산만 이뤄진다.

Physics(물리 연산 단계) - Internal Physics Update (물리 엔진 계산)

단계설명
ProcessAnimation앞서 계산된 애니메이션 그래프의 결과를 블렌딩한다.
OnAnimatorIK(int layerIndex)애니메이션 IK를 설정한다. IK pass가 활성화된 각 애니메이터 컨트롤러 레이어에 대해 한 번 호출한다.
WriteTransform모든 애니메이션화된 트랜스폼을 워커 스레드에서 씬에 작성한다.
WriteProperties다른 모든 애니메이션화된 프로퍼티를 메인 스레드에서 씬에 작성

🔹 OnTriggerEnter/stay/Exit()

  • Collider가 Trigger 일 때 물리 이벤트

🔹 OnCollisionEnter/stay/Exit()

  • Rigidbody와 충돌할 때 물리 이벤트

OnTriggerEnter/stay/Exit(),OnCollisionEnter/stay/Exit()
FixedUpdate 루프의 가장 마지막에 실행되며,
충돌 감지를 완료한 뒤에야 반응 로직이 실행됨.

🔹 yield WaitForFixedUpdate

  • 코루틴을 일시 중단하고, 다음 FixUpdate 이후에 재개하라는 코드
  • 물리 연산과 강하게 연관된 행동을 코루틴으로 제어할 때 사용

<코루틴에 대해서(링크)>

Input events(입력 처리 단계) → Game Logic

🔹 OnMouseDown/Over/UP

  • 마우스 이벤트에 대한 직접 처리
  • 보통 Input.GetKey, GetAxis등은 Update()에서 처리하지만 마우스 관련 직접 입력은 여기에서 받아서 처리 가능하다.

Game logic(게임 로직 단계) →Scene rendering

🔹 Update()

  • 매 프레임 호출
  • 일반적인 게임 로직을 처리한다.

🔹 yield return 객체

  • null, WaitForSecends등 코루틴 조건 객체에 따라 코루틴을 재개한다.

🔹 LateUpdate()

  • Update가 끝난 후 프레임 당 한 번 호출
  • 즉, Update에서 수행된 모든 계산은 LateUpdate가 시작할 때 완료됨
  • 유니티 문서에 따르면 LateUpdate는 일반적으로 3인친 카메라 사용한다고 한다
  • 캐릭터를 움직이고 Update로 방향을 바꾸게 하는 경우 LateUpdate에서 모든 카메라 움직임과 로테이션 계산을 수행할 수 있다. 이렇게 하면 카메라가 포지션을 추적하기 전에 캐릭터가 완전히 움직였는지 확인할 수 있다.
  • 즉, 카메라 추적 등 후처리에 적합

Game logic(게임 로직 단계) - 애니메이션 업데이트

위에서 정리하였기에 넘어가겠다.

Scene rendering →Gizmo rendering

이 단계는 비주얼 이펙트, 후처리, 커스텀 렌더링 관련 작업 시 중요하다.

메서드설명
OnPreCull()카메라가 씬을 잘라내기 전에 호출
OnWillRenderObject()오브젝트가 렌더링 대상일 때 호출
OnRenderObject()오브젝트 렌더링 시점
OnPostRender()렌더링이 완료된 직후
OnRenderImage()이미지 효과 후처리 (후처리 필터)

GIzmo & GUI Rendering → End of frame 또는 GUI (재귀)

OnGUI()는 새로운 UI 시스템인UI Toolkit, UGUI 이후 잘 안 쓰지만

디버깅용 인터페이스에 유용할 수 있음

OnDrawGizmos()에디터에서 Gizmo 그릴 때 호출
OnGUI()매 프레임마다 여러 번 호출됨 (Immediate Mode GUI용)

End of Frame → Pausing

🔹 yield WaitForEndOfFrame

  • 프레임이 완전히 끝나기 직전 실행되는 코루틴

Pausing → Decommissioning 또는 Physic로

🔹 OnApplicationPause()

  • 앱이 일시 정지될 때 호출
  • 모바일에서 백그라운드로 진입할 때

Decomminssioning(해제/종료 단계)

보통 이 단계에서 리소스 해제, 네트워크 연결 종료, 상태 저장 등을 처리한다.

🔹 OnApplicationQuit()

  • 어플리케이션 종료 직전에 호출
  • 에디터에서 사용자가 플레이 모드를 중지할 때 호출된다.

🔹 OnDisable()

  • 동작이 비활성화되거나, 비활성 상태일 때 호출

🔹 OnDestroy()

  • 오브젝트 존재의 마지막 프레임에 대해 모든 프레임 업데이트를 마친 후 호출
  • 오브젝트는 .Destory 또는 씬 종료에 대한 응답으로 파괴될 수 있다.

지금까지 실행 사이클 하나 하나 살펴보았다

이제 전체적인 흐름으로 다시 정리 이해를 굳혀보자

[에디터 단계]Reset()

[초기화]Awake()OnEnable()Start()

[게임 루프]
  ┌→ FixedUpdate()
  │    → 물리 처리 / 충돌 / RootMotion
  │
  └→ Update()
       → 일반 게임 로직
       → yield 등 코루틴 재개
       → LateUpdate() → 후처리

[렌더링 + 후처리]OnRenderObject()[일시정지 / 종료]OnApplicationPause()OnDisable()OnDestroy()

위 정리를 통해 오늘 얻은 인사이트를 정리해 보았다.

  • start(), Update, Awake()만 알고 있던 것과 달리, 많은 실행 사이클을 통해 게임 실행 흐름을 이해했다.
  • LateUpdate: 카메라 추적, 애니메이션 후처리 등은 여기서
  • 애니메이션 업데이트 사이클의 진행 위치와 과정을 간략하게라도 알게 되었다.

이 과정들을 통해 게임 개발에 있어서

지금까지 나무를 보고 막연하게 개발을 했었던 것 같다.

좀 더 넓은 시야를 가지고 개발에 임할 수 있게 된 것 같다.

이걸로 오늘의 회고를 대신하겠다(하하하하)

profile
천천히, 꾸준하게, 끝까지

0개의 댓글