ピュアJSで書かれていたライブラリがESModule化した時にUnity WebGLで読み込ませる方法が変わった

時雨堂のSoraというWebRTCアプリを利用している時、UnityではWebGL版のSDKが存在しないので「jslibを書いてUnityのコードから間接的にsora-js-sdkを呼び出してなんとかする」ような実装を書いていたのですが、Soraのサーバーを2024.xにアップグレードした際にライブラリもバージョンアップしようと思った所、sora.jsがES Module化したため、”sora.mjs”をそのままHTMLに読み込ませてもグローバル変数にSoraがエクスポートされないという問題がありました。

Before/After

Before(2022.x)

    <script src="./sora.js"></script>
    <script>
        console.log(Sora); // => Soraオブジェクトが見える
    </script>

After(2024.x)

    <script type="module">
        import Sora from "./sora.mjs";
        // こっち推奨らしい → import soraJsSdk from 'https://cdn.jsdelivr.net/npm/sora-js-sdk@2024.2.2/+esm'
        window.Sora = Sora;
    </script>
    <script>
        console.log(Sora); // => Soraオブジェクトが見える
    </script>

ちょっとダーティーな実装ですがこれでどんなESModulesでもグローバルスコープに渡してしまえばUnityのjslibから呼び出せるようになります。
SPA/SSRのお作法で誰もESMを意識せずに自然とコーディングしているので、逆に超シンプルなピュアHTMLでESMライブラリをどうやってフロントエンドに渡すか、みたいな知識が抜けていて小一時間hマってました。自戒。

ESM化の恩恵をUnity WebGLは受けられないという問題

Unity WebGLでJavascriptとのレイヤーとの通信を実装する場合、jslibというちょっと独特なjavascriptを書かなければならず、その上マトモな開発支援ツールが無いので、C#コードとjavascriptをバインディングする実装がテスタブルじゃないのが悩みです。このあたりガッツリやる(npmに依存する)ニーズがある場合、そもそも設計としてUnityを選ばない、という選択肢を考慮した方が良さそうです。

妄想

最近はThree.jsもWebGPUもいい感じに煮詰まってきたので、Webフロントエンドで3Dを実装する時に以下のような技術スタックの実装が選択肢に入るかな…と思っています。

  • React
  • Three.js
  • その他、フロントエンドで制御したいUI/ミドルウェア

ただ、3Dとして何をどこまでやるか、みたいな所ではかなり判断が分かれそうで

  • ポストプロセッシングでブラー効かせたり、Unity上でプロビジョニングしたアニメーションを再生したり、リッチな表現をしたい→Unity6+URPでシェーダー周りの互換性バグがかなり改善されて、Editorの実装がほぼそのまま出力できるようになった
  • タッチイベントに関するインタラクティブ表現→細かい所をThree.jsでやろうとすると死ぬ。デザインカンプや指示書があるような案件だとUnityの方が逆にデリバリーが速くなる

このあたりThree.jsで実装するとフラグメントシェーダーをゼロから書かなきゃいけなかったり、タッチイベントもイベントループ中の評価で3Dオブジェクトとインタラクティブの制御をガッツリ書かなければいけなかったりするので、Unityでやったほうが良い。

  • 相変わらずUnityのビルドは遅いのでリリースサイクルの速いアジャイルではプロジェクトのボトルネックになる可能性が高い
  • UIの記述量が多い
  • 3D実装とUIやその他の表現で作業者を分担できそう(ユーザー管理やコミュニケーション機能等)
  • クロスプラットフォームは考慮せず、Webへのデプロイが前提

逆に、デリバーまでの速度やリリースサイクル、システム全体で見た役割分担としてWebフロントエンドの技術で解決できる領域が多ければReactをフロントに据えた上で、IframeでUnityを埋め込んでデータをやり取りするのが良いんじゃないか、みたいな所管です。
UnityはUI ToolkitというuGUIに代わる新しいUIフレームワークが出てきて非ゲーム的なアプリもだいぶ作りやすくなってきたなという気持ちなのですが、WebGLへの統合時にフロントエンドとしてどうやっていくかという所は開発者に委ねられているので、自分の中で開発の方針として何らかの答えを持っておきたいところ(そもそもこのへん考えるといつECSに移行するかという話にもなってくる)。