웹으로 내보내기

더 보기

This page describes how to export a Godot project to HTML5. If you're looking to compile editor or export template binaries from source instead, read Compiling for the Web.

HTML5 내보내기로 Godot Engine에서 만든 게임을 브라우저에 게시할 수 있습니다. 이를 위해서 사용자의 브라우저가 WebAssembly <https://webassembly.org/>WebGL을 지원해야 합니다.

중요

브라우저 통합 개발자 콘솔을 사용하세요, JavaScript, 엔진, WebGL 에러와 같은 디버그 정보를 보기 위해선 보통 F12 키로 열 수 있습니다.

주의

브라우저에 관계 없이 HTML5 프로젝트를 iOS에서 실행시킬 때 심각한 버그가 존재합니다. 따라서 따라서 :ref:`iOS 네이티브 내보내기 기능 <doc_exporting_for_ios>`을 대신 사용하는 것을 권장합니다. 이렇게 하면 성능 또한 향상됩니다.

WebGL 버전

렌더러 선택에 따라 Godot은 WebGL 1.0 (GLES2) 또는 WebGL 2.0(GLES3)에서 실행됩니다.

프로젝트가 모든 브라우저를 지원하고 최적의 성능으로 동작하는 것을 원한다면 WebGL 1.0을 사용하는 것을 추천합니다.

Godot의 GLES3 렌더러는 하이엔드 기기에서 실행되는 것을 가정하므로 WebGL 2.0에서는 성능이 떨어질 수 있으며 지원되지 않는 기능 또한 존재합니다.

게다가 Safari 는 WebGL 2.0을 지원하지 않습니다. macOS에서는 Safari 15부터 WebGL 2.0를 지원하지만 iOS 브라우저(WebKit을 사용하는 모든 브라우저 해당)들은 아직 이를 지원하지 않습니다. 자세한 사항은 Can I use WebGL 2.0 를 참고하십시오.

내보내기 설정

실행 가능한 웹 내보내기 템플릿을 이용할 수 있다면, 편집기에서 씬 멈추기 버튼과 편집 중인 씬 실행 버튼 사이에 버튼이 나타나 테스트를 위해 빠르게 기본 브라우저에서 게임을 열 수 있습니다.

필요한 기능에 따라 내보내기 형식 을 선택할 수 있습니다:

:ref:`VRAM 압축방식<doc_import_images>`을 사용할 생각이라면 목표 플랫폼의 Vram Texture Compression 이 활성화 되어 있는지 확인해야합니다(For DesktopFor Mobile 을 둘 다 활성화 하면 용량은 커지지만 호환성이 증가합니다).

맞춤 HTML 셸 파일에 대한 경로가 주어진다면, 그것이 기본 HTML 페이지 대신 사용됩니다. Custom HTML page for Web export을 참고하세요.

Head Include는 생성된 HTML 페이지의 <head>에 나타납니다. 이걸로 웹 폰트나CSS가 포함된 타사 JavaScript API를 불러오거나, JavaScript 코드를 실행할 수 있습니다.

중요

프로젝트는 항상 각자의 HTML를 생성해야 합니다. 내보내기 과정에서, 내보내기 옵션에 따라 생성된 HTML의 text placeholders들이 대체됩니다. HTML을 직접 수정한 부분은 이후 내보내기 과정에서 사라지게 됩니다. 생성된 파일을 수정하려면 Custom HTML shell 옵션을 사용하십시오.

경고

Regular 를 제외한 다른 내보내기 타입 들은 C# 버전에서 아직 지원되지 않습니다.

제한사항

보안 및 개인 정보의 이유로, 네이티브 플랫폼에서 여유롭게 작동하는 많은 기능이 웹 플랫폼에서는 더 복잡합니다. 다음은 Godot 게임을 웹으로 이식할 때 알아야 할 제한사항 목록입니다.

중요

브라우저 공급자들은 만흔 기능들을 secure contexts 에서만 사용이 가능하도록 만들고 있는데, 때문에 그 기능들은 웹 페이지가 안전한 HTTPS 연결을 통해 배포되어야만 사용이 가능합니다(로컬 호스트는 보통 예외입니다).

Check the list of open HTML5 issues on GitHub to see if the functionality you're interested in has an issue yet. If not, open one to communicate your interest.

데이터 지속성을 위한 쿠키 사용

user://의 파일 시스템이 지속성을 갖길 원한다면 (특히 IndexedDB에서) 사용자는 반드시 쿠키를 허용해야합니다. iframe에 게임을 하는 것을 보여준다면, 서드 파티 쿠키도 허용해야합니다. 시크릿/비밀 브라우징 모드도 이 지속성을 방해합니다.

메서드 OS.is_userfs_persistent()user:// 파일 시스템이 존재하는 지를 확인할 수 있습니다, 하지만 어떤 경우에는 잘못된 반응을 가져올 수 있습니다.

Background processing

The project will be paused by the browser when the tab is no longer the active tab in the user's browser. This means functions such as _process() and _physics_process() will no longer run until the tab is made active again by the user (by switching back to the tab). This can cause networked games to disconnect if the user switches tabs for a long duration.

This limitation does not apply to unfocused browser windows. Therefore, on the user's side, this can be worked around by running the project in a separate window instead of a separate tab.

스레드(Threads)

위에서 설명했듯이 멀티쓰레딩은 적합한 내보내기 타입 을 지정해야만 사용이 가능하며 브라우저들의 지원이 아직 미미합니다.

경고

Requires a secure context. Browsers also require that the web page is served with specific cross-origin isolation headers.

GDNative

위에서 설명했듯이 GLNative는 적합한 내보내기 타입 을 지정해야만 사용이 가능합니다.

내보내기는 요구 GDNative .wasm 파일의 사본을 출력 폴더에 생성하며 이후 게임과 함께 서버에 업로드 되어야 합니다.

전체화면과 마우스 캡쳐

브라우저는 임의로 전체화면으로 가기를 하용하지 않습니다. 마우스 캡쳐하기도 마찬가지입니다. 대신 이러한 동작은 JavaScript 입력 이벤트의 결과로 일어나야합니다. Godot에서는, _input이나 _unhandled_input과 같은 입력된 이벤트 콜백 내에서 전체화면으로 들어가는 것입니다. Input 싱글톤을 쿼리하는 것으로는 충분하지 않고, 관련된 입력 이벤트가 현재 활성화되어야 합니다.

같은 이유에서, 전체화면 프로젝트 설정은 유효한 입력 이벤트 핸들러 내에서 엔진이 시작해야 작동합니다. 여기에는 HTML 페이지의 커스터마이징이 필요합니다.

오디오

크롬은 웹사이트가 오디오를 재생하는 법을 제한합이다. 반드시 플레이어가 클릭이나 키를 누르는 것으로 오디오를 재생해야 할 지도 모릅니다.

더 보기

구글은 웹 오디오 자동재생 규칙에 대한 정보를 제공합니다.

경고

마이크에 액세스 하기 위해서는 secure context <doc_javascript_secure_contexts> 가 필요합니다.

네트워킹(Networking)

저수준 네트워킹은 브라우저의 지원이 미미하여 구현되지 않았습니다.

현재는 HTTP client, HTTP requests, WebSocket (client) 와 :ref:`WebRTC <doc_webrtc>`가 지원됩니다.

The HTTP classes also have several restrictions on the HTML5 platform:

  • StreamPeer로 접근하거나 바꾸는 것이 불가능합니다

  • Threaded/Blocking 모드를 사용할 수 없습니다

  • 한 프레임에 여러 번 처리할 수 없습니다, 그래서 루프에서 폴링은 멈춥니다

  • 청크 응답 없음

  • 호스트 확인을 비활성화할 수 없습니다

  • 동일 출처 정책 <https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy>이 적용됨

클립보드

엔진과 운영체제간 클립보드 동기화는 브라우저가 Clipboard API 를 지원해야만 가능합니다. 또한 비동기적 API 의 특성으로 인해 GDScript에서의 접근시 안정성을 보장하지 못할 수 있습니다.

경고

:ref:`Secure context <doc_javascript_secure_contexts>`가 필요합니다.

게임패드

게임패드의 버튼이 눌리기 전까지는 감지되지 않습니다. 또한 브라우저/OS/게임패드의 조합에 따라 게임패드의 매핑이 잘못되었을 가능성이 존재합니다. 안타깝게도 Gamepad API 는 개인정보 보호 차원에서 모델/공급자/OS에 따라 게임패드를 다시 매핑할 수 있는 안정적인 방법을 지원하지 않습니다.

경고

:ref:`Secure context <doc_javascript_secure_contexts>`가 필요합니다.

부팅 스플래시가 표시되지 않습니다

기본 HTML 페이지는 로딩 중에 부팅 스플래시를 보여주지 않습니다. 하지만 이미지를 PNG 파일로 내보낼 수 있기 때문에, 맞춤 HTML 페이지 가 부팅 스플래시를 보여줄 수 있습니다.

쉐이더 언어 제약

GLES2 프로젝트를 HTML5로 내보내면 WebGL 1.0이 사용됩니다. WebGL 1.0은 동적 루프를 지원하지 않으므로 동적 루프를 사용하는 쉐이더는 작동하지 않습니다.

파일 전달하기

웹으로 내보내면 웹 서버로 보낼 여러 파일들을 생성합니다, 표시하기 위한 기본 HTML 페이지도 이에 속합니다. 맞춤 HTML 파일을 사용할 수 있습니다, Custom HTML page for Web export을 보세요.

생성된 .html 파일을 Apache 서버에서 DirectoryIndex로 사용할 수 있고 언제든지 index.html과 같은 이름으로 바꿀 수 있습니다, 이름은 기본적으로 파일에 의지하지 않습니다.

HTML 페이지는 브라우저 창에 최대 크기로 게임을 표시합니다. 이렇게 하면 게임을 게임의 크기가 있는 <iframe>에 넣을 수 있습니다, 흔한 웹 게임 호스팅 사이트에서 쓰는 방식이죠.

.html 파일 옆의 다른 내보낸 파일은 그대로 전달되지만, 이름은 바뀌지 않습니다. .wasm 파일은 엔진을 구현하는 이진 WebAssembly 모듈입니다. .pck 파일은 Godot 메인 팩으로 게임을 갖고 있습니다. .js 파일은 시작 코드가 있으며 .html 파일이 엔진에 접근하는 데 사용됩니다. .png 파일은 부팅 스플래시 이미지입니다. 기본 HTML 페이지에서는 쓰이지 않지만, 맞춤 HTML 페이지를 위해 포함됩니다.

.pck 파일은 이진 파일로, 보통 MIME 타입 application/octet-stream으로 전달됩니다. .wasm 파일은 application/wasm으로 전달됩니다.

조심

WebAssembly 모듈 (.wasm)을 application/wasm이외의 MIME 타입으로 전달하면 일부 시작 최적화를 방지할 수 있습니다.

서버 측에서 압축한 파일을 전달하는 것이 .pck.wasm 파일 같은 큰 사이즈의 파일에 적합합니다. WebAssembly 모듈은 압축을 특히 잘하는데, gzip 압축을 사용하여 원번 크기의 약 4분의 1까지 줄일 수 있습니다.

On-the-fly 압축을 지원하는 호스트: GitHub Pages (gzip)

On-the-fly 압축을 지원하지 않는 호스트: itch.io, GitLab Pages (supports manual gzip precompression)

스크립트에서 JavaScript 호출하기

웹 빌드에서 JavaScript 싱글톤이 구현됩니다. eval이라는 하나의 메서드를 제공하는데, 같은 이름의 JavaScript 함수와 비슷하게 작동합니다. 문자열을 인수로 가지며 JavaScript 코드로 실행합니다. 이걸로 Godot와 통합될 수 없는 스크립트 언어를 브라우저와 상호작용할 수 있게됩니다.

func my_func():
    JavaScript.eval("alert('Calling JavaScript per GDScript!');")

마지막 JavaScript 명령문의 값은 GDScript 값으로 변환되며 특정 경우에 eval()에 의해 반환됩니다:

  • JavaScript number는 GDScript에서 float로 반환됨

  • JavaScript boolean은 GDScript에서 bool로 반환됨

  • JavaScript stringGDScript에서 String으로 반환됨

  • JavaScript ArrayBuffer, TypedArray 그리고 DataView는 GDScript에서 PoolByteArray로 반환됨

func my_func2():
    var js_return = JavaScript.eval("var myNumber = 1; myNumber + 2;")
    print(js_return) # prints '3.0'

다른 JavaScript 값은 null로 반환됩니다.

HTML5 내보내기 템플릿은 보안성을 위해 싱글턴을 지원하지 않고 빌드 <doc_compiling_for_web>`되었을 수 있습니다. 그런 템플릿의 경우 HTML5 이외의 플랫폼에서 ``JavaScript.eval` 를 호출하면 null 을 반환합니다. 싱글턴의 지원여부는 아래와 같이 JavaScript :ref:`기능 태그 <doc_feature_tags>`로 확인할 수 있습니다:

func my_func3():
    if OS.has_feature('JavaScript'):
        JavaScript.eval("""
            console.log('The JavaScript singleton is available')
        """)
    else:
        print("The JavaScript singleton is NOT available")

my_func3() 처럼 3개의 큰따옴표 """ 로 둘러싸인 GDScript의 멀티라인 문자열은 JavaScript 코드의 가독성을 높이는데 유용합니다.

eval 메서드는 두번째 옵션인 Boolean 인자도 받으며 이 인자는 전역 실행 컨텍스트에서 코드를 실행하는 것들을 지정합니다, 전역 네임스페이스가 오염되지않기 위해 기본적으로 false입니다:

func my_func4():
    # execute in global execution context,
    # thus adding a new JavaScript global variable `SomeGlobal`
    JavaScript.eval("var SomeGlobal = {};", true)