스크립트 라이프 사이클

# 학습 과정 소개

기본 이벤트 함수의 라이프 사이클과 플레이할 때의 전체 라이프 사이클을 알아봅시다. 라이프 사이클을 이해하면 특정 함수가 언제 불리는지 예상할 수 있고, 전체 월드의 동작을 고려하며 제작할 수 있습니다.

# 기본 이벤트 함수의 라이프 사이클

월드에 필요한 로직을 만들기 위해서는 컴포넌트 스크립트를 만들어야만 합니다. 필요한 컴포넌트 스크립트를 만들 때 호출되는 시점을 예상해 의도한 로직에 맞게 동작할 수 있도록 작성해야 합니다. 라이프 사이클의 개념을 익혀두면 전체 흐름을 파악할 수 있기에 스크립트를 작성할 때 도움이 됩니다. 실행 환경에 따라 라이프 사이클의 기본 차이가 있습니다. 실행 환경은 크게 제작 중인 월드/출시된 월드, 서버/클라이언트로 구분됩니다.

함수 종류는 두 가지로 나눌 수 있습니다.

  * 기본 이벤트 함수: 메이플스토리 월드가 만든 함수들로 함수마다 특정 호출 시점이 정해져 있습니다. 크리에이터는 이 함수들의 호출 시점을 수정할 수 없고, 이 함수들의 시점을 기본으로 사용자 정의 함수를 만들어 호출해야 합니다.
  * 사용자 정의 함수: 사용자가 직접 정의하는 함수로 호출 시점을 기본 이벤트 함수와 엔티티 이벤트 함수에서 호출해 사용할 수 있습니다.   
기본적으로 함수는 어디선가 호출을 해야 합니다. 기본 이벤트 함수는 크리에이터가 호출하지 않아도, 특정 조건이 되었을 때 자동으로 호출되는 함수를 의미합니다. 이 함수들은 기본적으로 서버 공간에서 호출합니다 기본 이벤트 함수는 스크립트 에디터 창에서 Function 옆의  버튼을 눌러 추가할 수 있습니다. 기본 이벤트 종류로는 `OnInitialize`, `OnUpdate`, `OnBeginPlay`, `OnMapEnter`, `OnMapLeave`, `OnEndPlay`, `OnDestroy`, `OnSyncProperty` 가 있습니다. 각 함수에 대한 내용은 [MSW 기본 이벤트 함수](/docs/?postId=163)를 참고하세요.



기본 이벤트 함수의 흐름은 다음과 같습니다. 이 중 `OnUpdate`와 `OnSyncProperty`를 제외한 함수들의 흐름은 로그를 활용해 확인할 수 있습니다.

  1. 새로운 LIfeCycle 컴포넌트를 생성하고 `OnInitialize` `OnBeginPlay` `OnMapEnter` `OnMapLeave` `OnEndPlay` `OnDestroy` 함수를 추가합니다.
  2. 어떤 함수가 실행되었는지 알 수 있게 `log("함수 이름 실행")`을 작성합니다.
  3. LIfeCycle 컴포넌트를 DefaultPlayer에 추가합니다.
  4. `OnMapEnter` `OnMapLeave`를 확인하기 위해 맵을 추가하고, 포털을 사용해 연결합니다.
  5. 월드를 실행하고, 포털로 맵을 이동한 뒤, 실행을 종료합니다.
  6. 남겨진 로그의 순서는 아래와 같습니다.  
[gif](1683859157721a85006486490435ba29d7b5deea1e2f7)



먼저 `OnInitialize` `OnMapEnter` `OnBeginPlay`로그가 찍힙니다. 실행을 눌러 월드를 시작하면 시작 맵에 플레이어가 입장하기 때문에 월드 진입 시 최초 한 번 불리는 다른 두 함수와 불리게 됩니다. 포털을 이용해 맵을 이동하게 되면 시작 맵에서 떠나, 새로운 맵으로 진입하기 때문에 `OnMapLeave`, `OnMapEnter` 로그가 순차적으로 남습니다.

> 더 알아보기. 사용자 정의 함수는 시스템에서 자동으로 호출할 수 없기 때문에 기본 이벤트 함수로부터 호출을 받아야 실행됩니다. 만약, 크리에이터가 NewComponent에 MyNewFunction 함수를 만들었다면, 이 함수는 어디선가 호출을 해야합니다. 이때 호출하는 곳은 크리에이터가 만든 함수가 실행되길 원하는 시점(타이밍)과 같아야 합니다.

> 더 알아보기. 엔티티 이벤트(Entity Event)는 Event를 쉽게 제어할 수 있으며 사용자 정의 함수를 호출할 수 있습니다. 기본 이벤트 함수와 달리 정의된 특정 이벤트가 발생하는 시점에만 호출되며 라이프 사이클에 포함되지 않습니다

# 전체 플레이 라이프 사이클

서버와 클라이언트가 호출되는 전체 흐름을 알아봅시다. 플레이 라이프 사이클은 제작 중인 월드와 출시된 월드에서 약간의 차이가 있습니다. 가장 큰 차이점은 맵을 불러오는 방식입니다.

  * 제작 중인 월드에서 플레이할 때는 10개의 맵을 만들었더라도 플레이어가 있는 맵만 불러옵니다.
  * 출시된 월드에서는 플레이어 유무와 상관없이 모든 맵을 불러옵니다.



이와 같은 차이를 알고 있다면 제작 중인 월드 또는 출시된 월드에서 크리에이터 의도대로 동작하지 않는 무언가가 있을 때, 그 원인이 잘못된 코드에 있는지 사이클을 고려하지 않은 호출 때문인지를 파악할 수 있습니다.

#### World 개념 이해하기

월드는 최상위 레벨의 엔티티로써 실행 환경에 따라 하나씩 생성됩니다. 동시에 여러 개의 월드가 존재할 수 있지만, 월드끼리는 상호작용하며 영향을 끼치진 못합니다. 제작 중인 월드에서 테스트 플레이를 할 때는 편집용 월드와 테스트 플레이 월드가 공존하게 됩니다.

#### 제작 중인 월드에서 플레이 할 때

제작 중인 월드에서는 클라이언트 편집용 월드만 존재합니다. 편집용 엔티티는 `OnBeginPlay` `OnUpdate` `OnEndPlay`가 호출되지 않지만, 렌더링이 필요한 컴포넌트는 예외로 `OnUpdate`가 호출됩니다.

테스트를 위한 월드를 실행(플레이)하면 편집용 월드를 비활성화합니다. 그 후 로컬 서버 실행과 접속을 하고, 서버와 클라이언트에서 모두 테스트 플레이용 월드를 생성합니다. 이때 서버는 편집 중인 맵만 불러오는 것이 출시된 월드와의 차이점입니다. 그러나 제작 중인 월드에서 EntityService를 사용해 다른 맵의 엔티티를 얻거나, 플레이어가 포탈을 타고 다른 맵으로 이동하는 등 다른 맵에 접근한다면 해당 맵을 불러옵니다.

클라이언트는 플레이어의 엔티티가 있는 맵만 불러오며, 출시된 월드와 동일합니다. [png](1683859676106ae2fc05e6a434a63aa14a90883a59792)

#### 출시된 월드에서 플레이 시

출시한 게임의 서버는 시작 시 전체 맵을 불러오고, 클라이언트는 늘 플레이어 엔티티가 존재하는 맵만 불러옵니다.

[png](1683859725237548e1764d33b430ba798be79f395cf0d)

##### 참고 가이드

  * [함수](/docs/?postId=172)
  * [MSW 기본 이벤트 함수](/docs/?postId=163)
  * [Effective MSW 1](/docs?postId=559)