LOADING

加载过慢请开启缓存 浏览器默认开启

Godot Web Deployment & JS interop

2025/4/7 Godot

Emoji をクリックして、アロナちゃんの表情を変えよう!


目録


はじめに

この文章は、Godot で作ったゲームを Web 上にデプロイする方法やゲームと JavaScript の間に通信する方法を説明します。


ゲームをエクスポート

Godot を使用して Web 上でゲームプロジェクトを配布することはかなり簡単です。
先ず、Godot 側でプロジェクトを出力します。この階段の説明は省略させていただきます。

出力したものは以下のようになります:

Output detail 展開

output/
├─ libspine_godot.web.template_release.wasm32.nothreads.wasm
├─ game.apple-touch-icon.png
├─ game.audio.position.worklet.js
├─ game.audio.worklet.js
├─ game.icon.png
├─ game.js
├─ game.pck
├─ game.png
├─ game.side.wasm
├─ game.wasm
└─ game.html

Note: Web に表示するために、html ファイルの名前を index.html に変更する必要があります。


デプロイ

1. ローカルサーバーで起動

  1. Node.js をインストールします。
  2. command line (windows では ctrl + R で cmd を入力して実行) cd <path> で出力したフォルダに移動します。
  3. npx http-server を実行して、ローカルサーバーを起動します。

2. リモートサーバーにアップロード

これから GitHub Pages を例に説明します。他のサーバーでも似たような機能があると思います。

  1. 先ず、GitHub Pagesのクイックスタート の手順に従って、GitHub Pages の初期化を行います。
    要するに、<username>.github.io というリポジトリを作成して、そこに index.html をアップロードしたら、https://<username>.github.io/ というサイトにアクセスできるようになります。
  2. [Optional] fr 50%GitHub Pages は複数のリポジトリに対応できますから、Game 専用ページを作りたいなら、新しいリポジトリを作成し、Settings > Pages > Branch で main を選択して保存。そして、新しいページの URL は https://<username>.github.io/<repo>/ になります。
  3. ゲームなら、すべてのファイル (.html、.wasm、.pck、.js …) をアップロードすると、上記の URL でプレイできるようになります。

おまけに、Cloudflare を一緒に使用して、独自のドメインを設定することもできます。文章の長さゆえに、ここでは省略させていただきます。具体的な内容は、カスタムドメインとGitHub PagesについてRegister a new domain · Cloudflare を参照してください。

https://www.lunareclipse.cc/Games/Arona/ にアクセスして、冒頭のデモをプレイできます。

3. iframe を使ってゲームを埋め込む

もしこのブログみたいに、ほかの Web ページにゲームを埋め込みたいなら、以下のように iframe を html コードに追加して、ゲームを埋め込むことができます。

<iframe id="game" 
    src="https://www.lunareclipse.cc/Games/Arona/" 
    scrolling="no" 
    frameBorder="0" 
    allowfullscreen 
    style="width: 100%; max-width: 100%; aspect-ratio: 16/9;">
</iframe>

JavaScript と通信

先ず、Godot 側で JavaScriptBridge.eval() を使用して、JavaScript 側に godot という名前のグローバルオブジェクトを作成します。

JavaScriptBridge.eval("""
if (godot == undefined)
  var godot = { };  
""", true)

そして、このオブジェクトに changeExpression というメソッドを追加して、Godot 側の arona.set_expression() メソッドにリンクします。

class JS
class_name JS extends Node  
  
static var godot: JavaScriptObject # JavaScript Bridge  
static var callbacks: Dictionary[String, JavaScriptObject] = {}  
  
static func _static_init():  
    if not OS.has_feature("web"):  
       print("JavaScript is not supported on this platform.")  
       return  
  
    JavaScriptBridge.eval("""
if (godot == undefined)
  var godot = { };  
""", true)  
  
    godot = JavaScriptBridge.get_interface("godot")  
    print("[JS] Godot bridge initialized.")  
  
static func add_callback(function: Callable, js_name: String = "") -> void:  
    if js_name in callbacks:  
       print("[JS] Callback already exists.")  
       return  
       var callback_ref: JavaScriptObject = JavaScriptBridge.create_callback(function.callv)  
    if callback_ref == null:  
       print("[JS] Failed to create callback.")  
       return  
  
    if js_name.is_empty():  
       js_name = function.get_method().get_basename()      
  
    callbacks[js_name] = callback_ref  
    godot.set(js_name, callback_ref)  
  
static func remove_callback(js_name: String) -> void:  
    if js_name in callbacks:  
       godot.set(js_name, null)  
       callbacks[js_name].free()  
       callbacks.erase(js_name)  
    else:  
       print("[JS] Callback not found.")
JS.add_callback(arona.set_expression, "changeExpression")

これで、JavaScript 側で godot.changeExpression() を呼び出すと、Godot 側の arona.set_expression() が呼び出されます。

godot.changeExpression('happy')

Game ページでアドレスバーをクリックして、Ctrl+Shift+C を押して DevTools を開いて、Console に上記のコードを入力したら、Emoji をクリックすると同じようにアロナちゃんの表情が変わるはずです。


iframe を使う場合

iframe を使った場合、iframe に onload イベントを追加して:

<iframe id="game" 
    src="https://www.lunareclipse.cc/Games/Arona/" 
    scrolling="no" 
    frameBorder="0" 
    allowfullscreen 
    onload="onIframeLoaded();" 
    style="width: 100%; max-width: 100%; aspect-ratio: 16/9;">
</iframe>

<script>
function onIframeLoaded() {
    game = document.getElementById("game");
    godot = game.contentWindow.godot;
}
</script>

こうやて、iframe が読み込まれたときに Godot 側の godot オブジェクトにアクセスできます。

iframe を全画面表示

先ほどの game 変数を使って、以下のコードで iframe を全画面表示できます。

game.requestFullscreen();