Godot の通常プロジェクトをWEB としてエクスポートし実行する
本稿は WEB(HTML5) 向け GDEXTENSION の開発環境構築を行った際のメモの共有を意図した、一連の記事の1番目。「Godot GDEXTENSION build 環境構築のまとめ」と題する一連の記事を読んでいることを前提とする。
対象としている Godot エンジンのバージョンは 4.2.1。
本稿では簡単な Godot の通常のプロジェクト(GDEXTENSION を使っていない)をWEB としてエクスポートし実行するまでを説明する。
モチベーション、もしくは戯言
UNITY は WEB 出力をサポートしている。分かりやすいマンマシンインターフェースにリッチな2D/3D可視化、そして emscripten/wasm による C/C++ サポート、更にはWebSocket によるサーバー間通信。UNITY と WEB の組み合わせはフロントエンドの革新である。そう思っていたときが私にもあった。
そう思い、UNITYを触ってきたが、いかんせんプアなノートPCで勝負しなければならない身の上として、UNITYのプロジェクトを多数作って試すことが億劫となり、放置していた。しかし Godot エンジンを調べていくうちに同様のことができるのではないかと思い始めた。
やりたいことは、emscripten/wasm で機能実装を行い、もしくは ubuntu などで実行する他プロセスと通信を行い、2D/3D をサポートするマンマシンインターフェースを持つウエブアプリケーションを実装すること。あわよくばそれらを Android/iOS に移植すること。スマートフォンの持つ強力なセンサー類(カメラを含む)を用いることができればなお良し。そういうことが Godot エンジンでも実現できるのではないかと夢想した。
WEB 出力を考えた場合、UNITY と Godot エンジンの差はなんであろうか。色々あるが、ユーザーサイドによる C/C++ 開発可能範囲が大きい。UNITY では C# から C/C++ の関数呼び出しが可能である。単純な関数呼び出しだけで事足りる場合は良いが、複雑なことをやろうとするとバインディングフレームワークを自作する必要がある。やってみれば分かるが、適切なツールサポートが無い現状、これは非常に苦痛な作業だ。Godot エンジン GDEXTENSION では Godot エンジンドメインと C/C++ ドメインのバインディングが予め用意されている。この違いは非常に大きい。
WEB ターゲットの Godot GDEXTENSION プロジェクトはややこしい。Godot エンジンがバイトコード実行エンジンである上に、更に Godot GDEXTENSION の実行バイナリとして wasm のバイトコードに落とす必要があり、更にさらにそれらの実行環境が WEB ブラウザである。このように何重にも仮想化されたプロジェクトのための開発環境を開発する必要がある。これは果てしない道程に見える。だから面白いテーマであるにも関わらず、あまり流行っていないのだろう。とはいえ UNITY での道は途中で大きな欠落があるように見えるのに対し、Godot GDEXTENSION での道は細いながらも繋がっているように見える。歩いてみる価値があると思う。
WEB(HTML5)ターゲットでの Godot GDEXTENSION プロジェクト開発は粗く以下のステップが必要。
- Windows PC ターゲットとして課題を解決するプログラムを C/C++ で開発する
- Windows PC 向け GDEXTENSION として課題を解決する C/C++ プログラムを 移植する
- WEB 向け GDEXTENSION として課題を解決する C/C++ プログラムを 移植する
最初のステップは置くとして、二番目のステップの基盤は目途がついたと思う。本稿から始まる一連の記事は、三番目のステップの目ぼしをつけることを目的としている。
単純なプロジェクトの WEB エクスポート
先ず、単純な(GDEXTENSION を用いない)プロジェクトを作成し、それを WEB エクスポートして Windows PC の Chrome ブラウザで動作させることを試みる。
emsdk.bat の初期作成
WEB 関連のビルド環境設定用に 以下のファイルを %HOMEPATH% 配下に設置する。
※このファイルは今後成長させる予定。
%HOMEPATH%\emsdk.bat
SET PATH=%PATH%;"C:\Program Files\7-Zip"
SET PATH=%PATH%;C:\dev\tools\pkg-config\bin
SET PATH=C:\dev\tools\Python\Python312\Scripts;C:\dev\tools\Python\Python312;%PATH%
SET PATH=C:\dev\tools\mingw64\bin;%PATH%
SET PATH=C:\dev\godot-4.2.1-stable\bin;%PATH%
set PKG_CONFIG_EXE_DIR=C:\dev\tools\pkg-config\bin
set PKG_CONFIG_PATH=""
cd c:\dev
プロジェクトの作成とエクスポートテンプレートのダウンロード
コマンドプロンプトを開き、プロジェクトディレクトリを作成する。
Microsoft Windows [Version 10.0.22631.3007] (c) Microsoft Corporation. All rights reserved. C:\Users\user>.\emsdk.bat c:\dev>mkdir demos c:\dev>cd demos c:\dev\demos>mkdir demo_04 c:\dev\demos>cd demo_04
空の Godot エンジンプロジェクトを作成。
c:\dev\demos\demo_04>copy nul .\project.godot
Godot エンジンプロジェクトを起動する。
c:\dev\demos\demo_04>godot.windows.editor.x86_64.exe -e .
名無しのプロジェクトが起動する。
上部メニュー「エディター」の「エクスポートテンプレートの管理」を選択する。
「エクスポートテンプレートマネージャー」が開くので、「ダウンロードしてインストール」を選択する。
ネットワーク経由で、ダウンロードが始まるので待つ。
完了すると、”%USERPROFILE%\AppData\Roaming\Godot\export_templates\4.2.1.stable” というディレクトリが作成され、その配下にプリコンパイルされたエクスポートテンプレートがインストールされる。
ちなみに「フォルダーを開く」を押すと以下のようなファイルがインストールされたことが分かる。
結構なサイズのファイルが多数あるので、使わないものは削除してしまって良いだろう。
WEB 用のエクスポートテンプレートは以下のファイル。
web_debug.zip web_release.zip web_dlink_debug.zip web_dlink_release.zip
Godot 4.2 になって WEB 用のエクスポートテンプレートがデフォルトでインストールされるようになった。_dlink が付くものが GDEXTENSION 用。
簡単なプロジェクトの設置
唯一のシーンを作成する。左ペインの「シーン」タブ、「ルートノードの生成」から「その他のノード」を選択する。
「Node3D」を選択し、「作成」ボタンで作成を行う。
この Node3D はシーンであるので、ノード名を Sample に変えておく。これはシーンをファイルに保存するときのファイル名と一致させるため。
右ペインのノードツリーで「Node3D」を選択し、右クリックメニューから「子ノードを追加」を選択する。
「MeshInstance3D」を選択し、「作成」ボタンで作成を行う。
右ペイン「インスペクター」タブの「MeshInstance3D ->Mesh」を開く。
「<空>」の右側にある下矢印をクリックすると、選択肢が現れるので「新規BoxMesh」を選択する。
右ペインのノードツリーで「Sample」を選択し、右クリックメニューから「子ノードを追加」を選択する。
「Camera3D」を選択し、「作成」ボタンで作成を行う。これで「Sample」配下に「Camera3D」が設置された。
左ペインノードツリーで Camera3D を選択し、右ペイン「インスペクター」タブの「Node3D -> Transform」の項、”Position:x = 2″、”Position:y = 2″、”Rotation:x = -45″ に設定する。
同様に右ペインのノードツリーで「Sample」を選択し、右クリックメニューから「子ノードを追加」を選択する。
「Sample」配下に「DirectionalLight3D」を設置する。
左ペインノードツリーで 「DirectionalLight3D」 を選択し、右ペイン「インスペクター」タブの「Node3D -> Transform」の項、”Position:x = 2″、”Position:y = 2″、”Rotation:x = -45″ に設定する。
「MeshInstance3D」にスクリプトをアタッチする。
ファイルの中身は以下とする。
MeshInstance3D.gd
extends MeshInstance3D
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
rotate_y(delta*0.5)
このスクリプトは時間経過に応じて MeshInstance3D ノードを Y 軸周りに回転させるだけの簡単なもの。
ここまでできたら、Ctrl+”S” を押下して保存する。
「プロジェクト」メニューの「プロジェクトの設定」を選択する。
「プロジェクトの設定」ダイアログが開くので、左ペイン「アプリケーション -> 実行」を選択すると、右ペインに「メインシーン」の設定が現れるので、ディレクトリマークを選択すると .tscn ファイルが選択できるようになる。先ほど保存した、 ”Sample.tscn” を選択し「開く」で確定させる。
再度、Ctrl+”S” を押下して保存する。
“F5” を押下することにより実行することができる。
このプロジェクトは立方体を横方向に回転させるものであるが、Windows PCで動作確認することができた。
これを今度は WEB 向けにエクスポートする。
上部メニューの「プロジェクト」の「エクスポート」を選択すると「エクスポート」ダイアログが開く。
上部にある「追加」をマウス左クリックすると、選択可能なターゲットが羅列される。
ここで「Web」を選択する。
「エクスポート先のパス」を設定する。
ここでは、”c:/dev/demos/export/demo_04/web” というディレクトリを作成し、そこに “Sample.html” というファイルとして出力することにする。
左下の「全てエクスポート」が選択可能になるので、マウス左クリックする。
「すべてのエクスポート」ダイアログが開くので、「デバッグ」もしくは「リリース」を選択するとエクスポートが始まる。
例えば「デバッグ」を行えば以下のファイルがエクスポートされる。
c:\dev\demos\export\demo_04\web のディレクトリ 2024/01/19 19:50 <DIR> . 2024/01/19 22:17 <DIR> .. 2024/01/19 20:48 6,539 Sample.html 2024/01/19 20:48 12,190 Sample.apple-touch-icon.png 2024/01/19 22:13 806 Sample.apple-touch-icon.png.import 2024/01/19 20:48 7,199 Sample.audio.worklet.js 2024/01/19 20:48 5,578 Sample.icon.png 2024/01/19 22:13 771 Sample.icon.png.import 2024/01/19 20:48 452,317 Sample.js 2024/01/19 20:48 2,320 Sample.pck 2024/01/19 20:48 21,443 Sample.png 2024/01/19 22:13 754 Sample.png.import 2024/01/19 20:48 49,219,187 Sample.wasm 2024/01/19 20:48 5,793 Sample.worker.js 12 個のファイル 49,735,472 バイト 2 個のディレクトリ 124,392,665,088 バイトの空き領域
Python3 を用いた簡易実行確認
WEB 向けエクスポート生成物を WEB サーバーに設置すれば動作するはずであるが、やはりローカルで確認できる方法が欲しい。ここでは Python3 を用いて簡易 WEB サーバーを建て、Windows PC でのローカル確認を行う方法について述べる。
c:\dev\demos\export\demo_04\web ディレクトリに以下のファイルを設置する。
godot_python_web_server.py
#!/usr/bin/env python3
from http.server import HTTPServer, SimpleHTTPRequestHandler, test
import sys
class CORSRequestHandler (SimpleHTTPRequestHandler):
def end_headers (self):
self.send_header('Cross-Origin-Opener-Policy', 'same-origin')
self.send_header('Cross-Origin-Embedder-Policy', 'require-corp')
SimpleHTTPRequestHandler.end_headers(self)
if __name__ == '__main__':
test(CORSRequestHandler, HTTPServer, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)
この Python3 スクリプトは実行ディレクトリをドキュメントルートとして、簡易的な http サーバーを設置するもの。
以下の部分は、必要な http ヘッダを追加している。
self.send_header('Cross-Origin-Opener-Policy', 'same-origin')
self.send_header('Cross-Origin-Embedder-Policy', 'require-corp')
SimpleHTTPRequestHandler.end_headers(self)
詳細は以下のリンクを参照。
https://gist.github.com/nisovin/cf9dd74678641fb70902866c79692b17
新規コマンドプロンプトを開き、上記スクリプトを実行する。
Microsoft Windows [Version 10.0.22631.3007] (c) Microsoft Corporation. All rights reserved. C:\Users\user>.\emsdk.bat c:\dev>mkdir demos c:\dev>cd demos c:\dev\demos>cd export c:\dev\demos\export>cd demo_04 c:\dev\demos\export\demo_04>cd web c:\dev\demos\export\demo_04\web>python godot_python_web_server.py Serving HTTP on :: port 8000 (http://[::]:8000/) ...
Google Chrome を立ち上げ、以下のページを閲覧する。
以下のように Godot エンジンエディッタと同様のシーンが再生される。
残念なことに、現時点サポートされているブラウザは Chrome だけであるとのこと。
一応本サイトにも設置してみた。
This sample is using godot engine. license note is in https://godotengine.org/license/.
正しく動作していれば、立方体が半時計周りに回転する。
本稿の振り返り
本稿では Godot エンジンの通常のプロジェクト(GDEXTENSION を用いない)をWEB エクスポートし、Google Chrome ブラウザで実行した。
次稿では、WEB 向けビルドに必要なビルドツールチェーン emscripten 用の開発環境を構築する。
コメント