2020. 6. 17. 16:51ㆍDEFOLD/메뉴얼
Application lifecycle (어플리케이션 생명 주기)
Defold 어플리케이션 또는 게임의 라이프 사이클은 대규모로 단순합니다. 엔진은 초기화, 업데이트 루프(앱 및 게임에 가장 많은 시간이 소요됨) 및 종료의 세가지 실행 단계를 거칩니다.
대부분의 경우 Defold의 내부 작업에 대한 기본적인 이해만 필요합니다. 그러나 Defold가 작업을 수행하는 정확한 순서는 꼭 알아야만 합니다. 이 문서는 엔진이 처음부터 끝까지 응용 프로그램을 실행하는 방법을 설명합니다.
응용 프로그램은 엔진 작동에 필요한 모든 것을 초기화함으로써 시작된다. 메인 컬렉션을 로딩하고, init() Lua 함수(스크립트 컴포넌트, GUI 스크립트가 있는 GUI 컴포넌트)가 있는 모든 로드된 컴포넌트에 call init()를 호출한다. 이렇게 하면 사용자 지정 초기화를 수행할 수 있다.
그런 다음 애플리케이션은 해당 수명의 대부분을 사용하는 업데이트 루프로 들어갑니다. 각 프레임, 게임 오브젝트 및 포함된 컴포넌트가 업데이트됩니다. 스크립트 및 GUI스크립트의 update() 함수를 호출합니다. 업데이트 루프 메시지가 수신자에게 발송되는 동안 소리가 재생되고 모든 그래픽이 렌더링 됩니다.
그런 다음 애플리케이션은 업데이트 루프로 들어가 애플리케이션이 대부분의 수명을 소비하게 된다. 각 프레임, 게임 오브젝트 및 그 안에 포함된 컴포넌트가 업데이트된다. 모든 스크립트 및 GUI 스크립트의 update() 함수를 호출한다. 업데이트 루프 메시지가 수신자에게 전송되는 동안 소리가 재생되고 모든 그래픽이 렌더링된다.
애플리케이션의 라이프사이클은 어느 시점에서는 종료될 것이다. 애플리케이션이 업데이트 루프를 종료하기 전에 엔진이 최종화 단계에 진입한다. 로딩된 모든 게임 오브젝트를 삭제할 수 있도록 준비한다. 모든 객체 컴포넌트의 final() 함수를 호출하여 사용자 정의 정리를 허용한다. 그러면 객체가 삭제되고 main collection이 언로드된다.
Initialization
이 다이어그램에는 초기화 단계에 대한 자세한 설명이 포함되어 있습니다. 명확한 구별을 위해 "dispatch messages" 통과와 관련된 단계는 별도의 블록("spawn dynamic object")에 배치되었습니다.
엔진은 실제로 main collection이 로드되기 전에 초기화하는 동안 더 많은 단계를 밟습니다. 메모리 프로파일러, 소켓, 그래픽, HID(입력 장치), 사운드, 물리학 등이 설정되어 있습니다. 애플리케이션 구성("game.project")도 로드되고 설정됩니다.
엔진 초기화가 끝날 때 첫 번째 사용자 제어 가능 진입점은 현재 렌더 스크립트의 init() 함수에 대한 호출이다.
그런 다음 main collection이 로드되고 초기화됩니다. collection에 포함된 모든 게임 오브젝트는 변환(위치 변경), 회전 및 스케일링)을 자식에게 적용합니다. 그리고 모든 존재하는 컴포넌트의 init() 함수를 호출합니다.
게임 오브젝트 컴포넌트 init() 함수를 호출하는 순서는 불특정하다. 엔진이 동일한 컬렉션에 속하는 개체를 특정 순서로 초기화한다고 가정해서는 안 된다.
당신의 init() 코드는 새로운 메시지를 게시할 수 있고, Factory에 새로운 오브젝트를 생성하도록 지시하고, 삭제하기 위해 물체를 표시하고, 모든 종류의 일을 할 수 있기 때문에, 엔진은 다음에 완전한 "post-update" 패스를 수행한다. 이 패스는 메시지 전달, 실제 Factory 게임 오브젝트 발생, 오브젝트 삭제를 수행한다. 업데이트 후 패스는 대기 중인 메시지를 보낼 뿐만 아니라 collection 프록시로 보낸 메시지를 처리하는 "message dispatch" 시퀀스를 포함한다는 점에 유의하십시오. 프록시에 대한 후속 업데이트(하역 활성화 및 비활성화, 로딩 및 표시)는 이러한 단계에서 수행된다.
이 패스는 메시지 전달, 실제 팩토리 게임 오브젝트 스폰 및 오브젝트 삭제를 수행합니다. post-update 패스에는 대기중인 메시지를 보낼뿐만 아니라 collection 프록시로 전송 된 메시지를 처리하는 "dispatch messages"시퀀스가 포함되어 있습니다. 프록시에 대한 모든 후속 업데이트 (활성화 및 비활성화, 로드 및 언로드 표시)는 해당 단계에서 수행됩니다.
위의 다이어그램을 살펴보면 init() 중에 collection 프록시를 로드하고, 포함된 모든 개체를 초기화한 다음, 프록시를 통해 collection을 언로드할 수 있다는 것을 알 수 있다. 즉, 엔진이 init 단계를 떠나 update loop에 들어가기 전에 :
function init(self)
print("init()")
msg.post("#collectionproxy", "load")
end
function update(self, dt)
-- The proxy collection is unloaded before this code is reached.
print("update()")
end
function on_message(self, message_id, message, sender)
if message_id == hash("proxy_loaded") then
print("proxy_loaded. Init, enable and then unload.")
msg.post("#collectionproxy", "init")
msg.post("#collectionproxy", "enable")
msg.post("#collectionproxy", "unload")
-- The proxy collection objects’ init() and final() functions
-- are called before we reach this object’s update()
end
end
Update loop
업데이트 루프는 프레임마다 한번씩 긴 시퀀스를 통해 실행됩니다. 아래 다이어그램의 업데이트 시퀀스는 명확한 구별을 위해 논리적 시퀀스 블록으로 구분되어 있습니다. "Dispatch message"도 동일한 이유로 별도로 구분됩니다.
Input
사용 가능한 장치에서 입력을 읽고 입력 바인딩에 매핑 한 다음 전달합니다. 입력 포커스를 얻은 게임 오브젝트는 모든 컴포넌트의 on_input() 함수로 입력을 받습니다. 스크립트 컴포넌트가 있는 게임 오브젝트와 GUI 스크립트가 있는 GUI 컴포넌트는 컴포넌트 on_input()가 정의되어 있다면 해당 함수에 입력을 받습니다.
Input은 사용 가능한 장치에서 읽고 입력 바인딩에 대해 매핑한 다음 전송된다. 입력 포커스를 획득한 게임 객체는 모든 컴포넌트의 on_input() 함수로 입력을 받는다. 스크립트 컴포넌트가 있는 게임 오브젝트와 GUI 스크립트가 있는 GUI 컴포넌트는 정의되어 있고 입력 포커스를 획득한 경우, 두 구성요소의 on_input() 함수에 모두 입력된다.
입력 포커스를 획득하고 컬렉션 프록시 컴포넌트를 포함하는 모든 게임 개체는 프록시 컬렉션 내부의 구성 요소에 입력을 전달합니다. 이 프로세스는 활성화 된 컬렉션 프록시 내에서 활성화 된 컬렉션 프록시를 계속 재귀적으로 호출합니다.
Update
메인 컬렉션의 각 게임 오브젝트 컴포넌트가 순회됩니다. 이러한 컴포넌트 중 하나에 스크립트 update() 함수 가 있으면 해당 함수가 호출됩니다. 컴포넌트가 콜렉션 프록시인 경우, 프록시 콜렉션의 각 컴포넌트는 위 다이어그램의 "업데이트" 순서에있는 모든 단계로 반복적으로 업데이트됩니다.
메인 컬렉션의 각 게임 오브젝트 컴포넌트를 순회한다. 이러한 컴포넌트 중 하나라도 스크립트 update() 함수이 있으면 이 함수가 호출된다. 컴포넌트가 collection 프록시인 경우, 프록시 컬렉션의 각 컴포넌트는 위의 다이어그램에서 "update" 시퀀스의 모든 단계에 따라 반복적으로 업데이트된다.
게임 오브젝트 컴포넌트 update() 함수가 호출 되는 순서는 지정되어 있지 않습니다. 엔진이 동일한 컬렉션에 속하는 객체를 특정 순서로 업데이트한다고 가정해서는 안됩니다.
다음 단계에서는 게시된 모든 메시지가 발송된다. 수신기 구성요소의 on_message() 코드는 추가 메시지를 게시할 수 있으므로, 메시지 발송자는 메시지 대기열이 비어 있을 때까지 메시지로 작성된 게시물을 계속 발송할 것이다. 그러나 메시지 발송자가 수행하는 메시지 대기열을 통해 실행되는 횟수에는 제한이 있다. 자세한 내용은 메시지 전달 및 "고급 항목" 절을 참조하십시오.
충돌 오브젝트 컴포넌트의 경우, 물리 메시지(Collision, 트리거, Ray_cast response 등)는 on_message() 함수가 있는 스크립트를 포함하는 모든 구성요소에 아우를수 있는 게임 오브젝트 전체에 걸쳐 전송된다.
Render update
렌더 업데이트 블록은 @render 소켓(카메라 구성요소 set_view_projection 메시지, set_clear_color messages 등)으로 메시지를 발송한다. 그런 다음 렌더 스크립트 update()가 호출된다.
Post update
언로드로 표시된 메모리 수집 프록시에서 언로드됩니다 ( "디스패치 메시지" 시퀀스 중에 발생 함). 삭제 표시된 모든 게임 오브젝트는 해당 컴포넌트의 모든 final() 함수를 호출합니다 (있는 경우). final() 함수의 코드는 종종 새로운 메시지를 큐에 게시하므로 "디스패치 메시지" 패스가 나중에 실행됩니다.
update 이후 post update 시퀀스가 실행됩니다. 언로딩으로 표시된 메모리 수집 프록시에서 언로드됩니다 ("디스패치 메시지" 시퀀스 중에 발생). 삭제 표시된 게임 오브젝트는 모든 컴포넌트의 final() 함수가 있는 경우 호출한다. final() 함수의 코드는 종종 새로운 메시지를 대기열에 게시하므로 "메시지 디스패치" 패스가 이후에 실행된다.
게임 오브젝트를 스폰하라는 팩토리 컴포넌트는 다음에 그렇게 할 것입니다. 마지막으로, 삭제 표시된 게임 오브젝트는 실제로 삭제됩니다.
업데이트 루프의 마지막 단계에는 @system 메시지(expit, reboot 메시지, 프로파일러 전환, 비디오 캡처 시작 및 중지 등)의 전송이 포함된다. 그러면 그래픽이 렌더링된다. 그래픽 렌더링 중에는 비디오 프로파일러 렌더링과 마찬가지로 비디오 캡처가 수행된다(디버깅 설명서 참조).
Frame rate and collection time step (프레임 속도 및 collection 시간 단계)
초당 프레임 업데이트 수 (초당 업데이트 루프 실행 횟수와 동일)는 프로젝트 설정에서 설정하거나 set_update_frequency 메시지를 @system 소켓에 보내 프로그래밍 방식으로 설정할 수 있습니다. 또한 set_time_step 메시지를 프록시에 전송하여 수집 프록시의 시간 단계를 개별적으로 설정할 수 있습니다.
컬렉션의 시간 단계를 변경해도 프레임 속도에는 영향을 미치지 않습니다. 물리 업데이트 시간 단계 및 update ()에 전달 된 dt 변수에 영향을 줍니다. 또한 시간 단계를 변경해도 각 프레임마다 update()가 호출되는 횟수는 변경되지 않으며 항상 정확히 한 번입니다.
Finalization
응용 프로그램이 종료되면 먼저 마지막 업데이트 루프 시퀀스를 완료하고, 이 시퀀스는 각 프록시 컬렉션의 모든 게임오브젝트를 삭제하는 수집 프록시를 언로드합니다.
이 작업이 완료되면 엔진은 메인 컬렉션과 그 객체를 처리하는 최종화 시퀀스에 들어간다.
컴포넌트는 final() 함수를 먼저 호출한다. 후속 메시지 발송이 뒤따른다. 마지막으로 모든 게임 오브젝트가 삭제되고 메인 컬렉션이 언로드됩니다.
'DEFOLD > 메뉴얼' 카테고리의 다른 글
8. Import 2D graphics (0) | 2020.06.17 |
---|---|
7. Importing assets (0) | 2020.06.17 |
5. Addressing (0) | 2020.06.17 |
4. Building blocks (0) | 2020.06.16 |
3. 라이브러리 (0) | 2020.06.16 |