웹으로 내보내기

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


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


There are significant bugs when running HTML5 projects on iOS (regardless of the browser). We recommend using iOS' native export functionality instead, as it will also result in better performance.

WebGL version

Depending on your choice of renderer, Godot can target WebGL 1.0 (GLES2) or WebGL 2.0 (GLES3).

WebGL 1.0 is the recommended option if you want your project to be supported on all browsers with the best performance.

Godot's GLES3 renderer targets high end devices, and the performance using WebGL 2.0 can be subpar. Some features are also not supported in WebGL 2.0 specifically.

Additionally, while most browsers support WebGL 2.0, this is not yet the case for Safari. WebGL 2.0 support is coming in Safari 15 for macOS, and is not available yet for any iOS browser (all WebKit-based like Safari). See Can I use WebGL 2.0 for details.

내보내기 설정

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

You can choose the Export Type to select which features will be available:

  • Regular: is the most compatible across browsers, will not support threads, nor GDNative.

  • Threads: will require the browser to support SharedArrayBuffer. See Can I use SharedArrayBuffer for details.

  • GDNative: enables GDNative support but makes the binary bigger and slower to load.

If you plan to use VRAM compression make sure that Vram Texture Compression is enabled for the targeted platforms (enabling both For Desktop and For Mobile will result in a bigger, but more compatible export).

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

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


Each project must generate their own HTML file. On export, several text placeholders are replaced in the generated HTML file specifically for the given export options. Any direct modifications to that HTML file will be lost in future exports. To customize the generated file, use the Custom HTML shell option.


Export types other then Regular are not yet supported by the C# version.


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


Browser vendors are making more and more functionalities only available in secure contexts, this means that such features are only be available if the web page is served via a secure HTTPS connection (localhost is usually exempt from such requirement).

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:// 파일 시스템이 존재하는 지를 확인할 수 있습니다, 하지만 어떤 경우에는 잘못된 반응을 가져올 수 있습니다.


As mentioned above multi-threading is only available if the appropriate Export Type is set and support for it across browsers is still limited.


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


As mentioned above GDNative is only available if the appropriate Export Type is set.

The export will also copy the required GDNative .wasm files to the output folder (and must be uploaded to your server along with your game).

전체화면과 마우스 캡쳐

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

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


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

더 보기

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


Access to microphone requires a secure context.


Low level networking is not implemented due to lacking support in browsers.

Currently, only HTTP client, HTTP requests, WebSocket (client) and WebRTC are supported.

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 synchronization between engine and the operating system requires a browser supporting the Clipboard API, additionally, due to the API asynchronous nature might not be reliable when accessed from GDScript.


Requires a secure context.


Gamepads will not be detected until one of their button is pressed. Gamepads might have the wrong mapping depending on the browser/OS/gamepad combination, sadly the Gamepad API does not provide a reliable way to detect the gamepad information necessary to remap them based on model/vendor/OS due to privacy considerations.


Requires a secure context.

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

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

Shader language limitations

When exporting a GLES2 project to HTML5, WebGL 1.0 will be used. WebGL 1.0 doesn't support dynamic loops, so shaders using those won't work there.

파일 전달하기

웹으로 내보내면 웹 서버로 보낼 여러 파일들을 생성합니다, 표시하기 위한 기본 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까지 줄일 수 있습니다.

Hosts that provide on-the-fly compression: GitHub Pages (gzip)

Hosts that don't provide on-the-fly compression: 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 export templates may be built without support for the singleton to improve security. With such templates, and on platforms other than HTML5, calling JavaScript.eval will also return null. The availability of the singleton can be checked with the JavaScript feature tag:

func my_func3():
    if OS.has_feature('JavaScript'):
            console.log('The JavaScript singleton is available')
        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)