Unity : 스크립트 생명 주기


https://docs.unity3d.com/2023.2/Documentation/Manual/ExecutionOrder.html

매뉴얼 버전: 2023.2
영문 문서 보고 번역 및 요약했다.

alt text

이 이벤트 함수들은 MonoBehaviour 붙인 스크립트에서 선택적으로 실행되게 할 수 있는 내장 이벤트들이다.
Application, SceneManager, Camera 같은 클래스들을 이용하면 이것들 말고도 다른 이벤트를 등록할 수 있다.

처음 씬이 load될 때

  • Awake: 오브젝트 인스턴스 생성되면 가장 처음으로 호출됨.
    시작할 때 게임 오브젝트가 비활성화됐다면 활성화될 때까지 호출 안됨.
  • OnEnable: 오브젝트가 활성화되면 Awake 다음, Start 이전에 호출됨.

서로 다른 오브젝트끼리의 AwakeOnEnableStart 순서는 보장되지 않음.
A의 Start가 호출된 이후 B의 Awake가 호출될 수도 있다.

씬이 load되고 unload될 때

씬이 load되고 unload될 때 콜백 함수를 받을 수 있게 해주는
SceneManager.sceneLoaded와 SceneManager.sceneUnloaded 이벤트는 위 그림에 없다.
sceneLoaded 알림은 OnEnable 이후, Start 이전에 받는다.

Unity 실행 시 특정 메서드를 자동으로 호출하게 만드는 RuntimeInitializeOnLoadMethodAttribute의 BeforeSceneLoad, AfterSceneLoad를 사용하면 특정 메서드를 씬 로드 이전과 이후에 실행되게 할 수 있다.

에디터

  • Reset: 스크립트가 오브젝트에 처음 부착되거나 Reset을 눌렀을 때 스크립트의 속성을 초기화한다. (스크립트 컴포넌트 우측 상단 점 세개 눌러보면 Reset 버튼이 있다.)
  • OnValidate: 스크립트의 속성값이 수정되거나, 오브젝트를 메모리로 불러오며 역직렬화 과정이 일어날 때 호출된다.

오브젝트를 메모리로 불러올 때, 직렬화되어 저장된 데이터들을 역직렬화하여야 한다.
에디터에서 씬을 열거나, domain reload가 일어난 후에 역직렬화가 일어난다.
이미 메모리에 존재하는 오브젝트를 단순 참조할 때는 역직렬화할 필요 없다.

domain reload: 코드 변경 후 컴파일이 완료되거나 플레이 모드를 종료할 때 Unity가 스크립트를 다시 로드하는 과정

첫 프레임 업데이트 이전

  • Start: 스크립트 인스턴스가 활성화돼있을 때 첫 프레임 업데이트 이전에 호출됨.

프레임 사이에

  • OnApplicationPause: 일시중지를 누르면 프레임 끝에 호출된다. 정지된 화면을 보여주기 위해 프레임 하나가 추가로 만들어진다.

업데이트 순서

게임 로직, 상호작용, 애니메이션, 카메라 위치 등을 조작하려면 보통 Upadte를 이용한다.
그냥 Update 말고도 다른 함수들도 있다.

  • FixedUpdate: 프레임 단위가 아니라 고정된 in-game 시간 간격대로 발생한다.
    업데이트들은 고정돼있고 frame rate는 가변적이기 때문에,
    frame rate가 높을 땐 frame 사이에 fixed update가 하나도 발생하지 않을 수 있고,
    frame rate가 낮을 땐 frame당 여러 개의 fixed update들이 발생할 수 있다.
    모든 물리 계산과 update들은 FixedUpdate 직후에 발생한다.
    frame rate에 독립적이라, FixedUpadte에서 이동을 계산할 때 Time.deltaTime을 곱할 필요 없다.
    fixed update들 사이의 간격은 Time.fixedDeltaTime으로 정의돼있다.
    fixedDeltaTime은 에디터의 Time settings의 Fixed Timestep 속성값을 건드리거나 스크립트를 통해 직접 설정 가능하다.
  • Update: 프레임 당 한 번 호출된다.
  • LateUpdate: Update가 끝난 뒤 프레임 당 한 번 호출된다. 3인칭 시점 카메라에 자주 사용된다.

애니메이션 업데이트 루프

MonoBehaviour에 의해 호출되는 애니메이션 루프 콜백 함수들

  • MonoBehaviour.OnAnimatorMove: 루트 모션 처리를 위한 콜백
  • MonoBehaviour.OnAnimatorIK: Inverse Kinematics를 설정하기 위한 콜백

StateMachineBehaviour에 의해 호출되는 애니메이션 관련 이벤트 함수들

  • StateMachineBehaviour.OnStateMachineEnter
  • StateMachineBehaviour.OnStateMachineExit
  • StateMachineBehaviour.OnStateEnter
  • StateMachineBehaviour.OnStateUpdate
  • StateMachineBehaviour.OnStateExit
  • StateMachineBehaviour.OnStateMove
  • StateMachineBehaviour.OnStateIK

렌더링

이 실행 순서는 Built-in Redner Pipeline에만 적용되며, SRP, URP, HDRP는 약간 다르다.
렌더링 직전에 무언가를 발생시키고 싶다면, Application.onBeforeRender를 이용하라.

  • OnPreCull: 카메라가 필요없는 씬을 잘라내기(cull) 전에 호출된다.
  • OnBecameVisible/OnBecameInvisible: 오브젝트가 아무 카메라에 보여지거나, 안 보여질 때 호출.
    OnBecameInvisible이 플로우 차트에 없는 이유는 오브젝트가 아무 때나 안 보여질 수 있기 때문.
    (카메라의 이동, 오브젝트 비활성화, 오클루전 컬링 등 다양한 이유로 인해 안 보여질 수 있다)
  • OnWillRenderObject: 오브젝트가 각 카메라에 보일 때 한 번만 호출된다.
  • OnPreRender: 카메라가 씬을 렌더링하기 전에 호출된다.
  • OnRenderObject: 모든 기본적인 렌더링 과정이 끝나고 난 뒤에 호출된다.
    이때 GL 클래스나 Graphics.DrawMeshNow를 통해 custom geometry를 그릴 수 있다.
  • OnPostRender: 카메라가 씬 렌더링을 완료한 이후에 호출된다.
  • OnRenderImage: 씬 렌더링이 완료된 이후에 post-processing을 할 수 있도록 호출된다.
  • OnGUI: IMGUI에서 GUI 이벤트를 처리하기 위해 호출된다.
  • OnDrawGizmos: 씬 뷰에 Gizmo들을 그릴 때 사용된다. 게임 실행 여부와 상관없이 동작하며, 에디터 전용이다.

IMGUI(Immediate Mode GUI): 일반적으로 사용하는 UGUI와는 다른 GUI 시스템. 인게임 디버깅 도구, 커스텀 인스펙터 등에 쓰인다. 매 프레임 UI를 다시 그리므로 Canvas 기반의 UGUI보다 성능이 안 좋다.

코루틴

일반적인 코루틴 업데이트들은 Update 함수가 반환된 뒤에 실행된다.
코루틴은 주어진 YieldInstruction이 끝날 때까지 실행을 중단(yield)하는 함수이다.

  • yield: 다음 프레임에서 모든 Update 함수들이 실행된 이후에 재개됨.
  • yield WaitForSeconds: 지정된 시간이 지나고, 해당 프레임의 모든 Update 함수들이 호출된 이후에 재개됨.
  • yield WaitForFixedUpdate: 모든 FixedUpdate가 호출된 이후에 재개됨. 코루틴이 FixedUpdate 이전에 yield했다면, 현재 프레임의 FixedUpdate들이 끝난 이후에 바로 재개됨.
  • yield WWW: WWW 다운로드가 끝나면 재개됨.
  • yield StartCoroutine: 다른 코루틴을 시작시킨 뒤 다시 재개될 때까지 기다림.

WWW class: 웹 요청을 통해 데이터를 다운로드하거나 업로드할 때 사용되는 클래스. 2017 이전 버전 유니티에서 사용됐으며, 현재는 UnityWebRequest로 대체됨. 이해하기 쉽고 구현이 간단해서 아직 쓰기도 함.

오브젝트가 파괴됐을 때

  • OnDestory: 파괴될 오브젝트의 마지막 프레임의 모든 작업이 끝나고 난 뒤 호출됨
    (오브젝트는 씬을 닫거나 Object.Destoy을 호출할 때 파괴됨)

닫을 때

이 함수들은 씬에 있던 모든 활성화된 오브젝트들에서 호출됨

  • OnApplicationQuit: 이 함수는 프로그램이 종료되기 전에 모든 게임 오브젝트에서 호출됨. 에디터에선 플레이 모드 종료할 때 호출됨.
  • OnDisable: 컴포넌트가 비활성화되거나, 오브젝트가 비활성화되면 호출됨.