![画像](https://habrastorage.org/webt/x0/dv/es/x0dvesauwzmvumvshe8iqgxi4oa.jpeg)
WebGLマスタリング
ゲームVikings:War of Clansは、クロスプラットフォームエンジンUnity 3Dで作成されました。これにより、モバイルデバイスからブラウザーまで、25を超えるプラットフォームでアプリケーションを実行できます。 すでにAdobe Flashの経験がありましたが、このプロジェクトではWebGLテクノロジーを選択しました。その理由は次のとおりです。
- 既存のプロジェクトのビジネスロジックをほとんど変更せずに転送できます。
- WebGLテクノロジーは、ほとんどすべての最新ブラウザーと互換性があり、追加のプラグインを必要としません。
- Unity Technologiesは、WebGLが彼らにとっての優先技術であることを隠しておらず、新しいバージョンが追加されるたびにエンジンが著しく進歩します。ドキュメントの改善、バグの修正、機能の追加です。
Unity開発者が質の高い技術サポートと広範なドキュメントを提供していることは注目に値します。 プロジェクトの作業中に、ユーザーガイドおよびこのエンジン専用のフォーラムでWebGLの制限に関する必要な情報をすべて受け取ったため、あなたは間違いなく助けを求められません。
翻訳の難しさ
WebGLビルドをビルドするために、Unityエンジンは複雑な一連のアクションを実行します。MonoC#コンパイラーを使用してゲームコードを中間(IL)コードに変換し、IL2CPPテクノロジーを使用してC ++言語コードを取得します。 Emscriptenコンパイラを使用してプロジェクトを作成します。 その結果、Unity 3Dエンジンが提供するすべての.Net機能が最終ビルドで使用できるわけではありません。 たとえば、マルチスレッドはサポートされていません。System.Net.Socketsは機能しません。
Webバージョンに完全に移行するには、多くの問題を排除する必要がありました。
WebSockets実装 。 ネットワークの場合、最小限の変更でWebソケットを介してサーバーを操作できるラッパーが作成されました。 Unity Asset Storeには簡単な例があります。
マルチスレッドの欠如 。 モバイルバージョンでさまざまなプロセスが別々のスレッドで並行して起動され、完了するまで中断されなかった場合、Webバージョンのシングルスレッド特性は、アプリケーションのフリーズを防ぐために異なるアプローチを必要としました。 これを行うために、すべてのアクションをコルーチンに転送し、時間の経過とともに負荷分散を実現しました。
タブを開く 。 Unityは、記録されたユーザーアクションをバッファーに移動し、フレームの内部更新中にそれらを渡します。 この状況では、ブラウザー保護により別のウィンドウを開くことができません。 この問題は、エンジンの小さな拡張-マウスイベントが直接スクロールされるネイティブブラウザプラグインによって解決されました。
OpenURL: function(url){ window.open(Pointer_stringify(url)); }
したがって、必要なすべてのウィンドウを開くことができました。 WebGL用のプラグインの作成については、 公式ドキュメントおよび開発者のブログに記載されています。
フォント ある時点で、キャラクターの表示を改良する必要がありました。 特に、象形文字は次のように入力する必要があります。ユーザーはラテン文字の組み合わせを入力します。ラテン文字は日本語、中国語、または韓国語の文字に変換されます。 Unity自体では、このメソッドは提供されていませんが、そのような機能はブラウザーにあります。 別のプラグインを使用して実装しました。 さらに、WebGLは、同じFlashのネイティブアプリケーションとは異なり、システムフォントにアクセスできません。 そのため、それらをプロジェクトに直接追加しました。もちろん、アセンブリのサイズが大きくなりました。
テクスチャ品質設定 。 テクスチャの圧縮品質とビルドサイズのバランスを調整するのに多くの時間がかかりました。 モバイルバージョンから転送されたテクスチャのうち、ピンチできるものとそうでないものを実験的に見つける必要がありました。 徐々に、最適な設定になりましたが、現在は自動的に設定されています。
ゲームにはテクスチャ用のアトラスがいくつかあり、原則として、DXT1およびDXT5圧縮を使用します(それらのアルファチャネルの有無に応じて)。 2つのアトラスは例外です。圧縮(グラデーション付きのテクスチャ、数字または文字のボタン)に非常に反応しないアトラスと、絵文字のアトラスが含まれています。 これらの場合、RGBA32を使用します。
アトラスの外側にある他のすべてのテクスチャのサイズを小さくするには、DXT1CrunchedおよびDXT5Crunched形式が適しています。 現時点では、AssetPostprocessorのOnPreprocessTextureメソッドを再定義しました。これにより、プロジェクト内のすべてのテクスチャにこれらの設定を自動的に適用できました。
サードパーティサービス 。 モバイルゲームで効果的に使用されるサードパーティライブラリは、WebGLプロジェクトの構築時に正しく機能しないか、まったく機能しない場合があることに備えてください。 このような状況での最善の解決策は、代替手段を見つけることです。 たとえば、Facebookでの承認には、さらにネイティブJavaScriptプラグインを使用しました。 これにより、ページのロード時にすでにユーザーを識別し、事前にゲームに必要な権限を取得できます。
Unity 5.2から5.6への移行 。 開発プロセス中に、Unity 5.2からバージョン5.6に切り替える必要がありました。UnityLoaderが追加され、いくつかの重大な問題が修正されました(たとえば、ページのリロード時のメモリビルドクラッシュ)。 これらの変更により、アプリケーションの初期化が大幅に簡素化されました。 以下の両方のバージョンのビルドのダウンロードコードを見ることができます。
Unity 5.2:
var canvas = document.createElement("canvas"); canvas.style.width = "100%"; canvas.style.height = "100%"; canvas.addEventListener("contextmenu", function(e) { e.preventDefault() }), canvas.id = "canvas"; gameContainer.appendChild(canvas); if (consts.isDebug) { createScript('unity52/module_pre_debug.js?v=' + consts.appVersion); document.WebExistsGLCallback = function() { Module.postRun.push(unityHelper.postRun); createScript('Debug/Release/fileloader.js?v=' + consts.appVersion); createScript('unity52/module_post_debug.js?v=' + consts.appVersion); tracker.load(); }; createScript('unity52/UnityConfig.js?v=' + consts.appVersion); } else { createScript('unity52/module_pre.js?v=' + consts.appVersion); document.WebExistsGLCallback = function() { Module.postRun.push(unityHelper.postRun); createScript('Release/fileloader.js?v=' + consts.appVersion); createScript('unity52/module_post.js?v=' + consts.appVersion); tracker.load(); }; createScript('unity52/UnityConfig.js?v=' + consts.appVersion); }
Unity 5.6:
unityHelper.url = consts.isDebug ? "Debug/Build/Debug.json" : "Build/WebGL.json"; Module = UnityLoader.instantiate(gameContainer, unityHelper.url, { onProgress: function(a, b) { preloader.setProgress(b); }, Module: { resolveBuildUrl: function(buildUrl) { return (buildUrl.match("/(http|https|ftp|file):\/\//") ? buildUrl :unityHelper.url.substring(0, unityHelper.url.lastIndexOf("/") + 1) + buildUrl) + "?v=" + consts.appVersion; }, postRun: [unityHelper.postRun], }, }).Module;
新しいプロジェクトの新しい経験
Vikings:War of Clansのデスクトップバージョンを実装するのに半年かかりました。 ほとんどの場合、新しいUIを作成し、約2か月でWebGLへの移行に技術的な作業を行いました。
玉座に就く:戦争の王国、私たちは何をすべきか、そしてどの時間枠でそれを満たすことができるかをすでに知っていました。 これにより、2番目のプロジェクトは、わずか4か月でより高速にWebプラットフォームに切り替わりました。 どちらの場合も、デスクトップバージョンが生産に近づいている間にモバイルゲームが機能を拡張したため、UIの個々の要素はすでにプロセスで調整されていることに注意してください。
![画像](https://habrastorage.org/webt/q0/kp/km/q0kpkmnaqwjco7r5gbrowk4_zi8.jpeg)
開発者向けのヒント
- アプリケーションのアーキテクチャでロジックとプレゼンテーションを分離し、プロジェクトに単一のコードベースを割り当てようとします。 これにより、コードの重複の問題を回避し、使用するすべてのプラットフォームを簡単にサポートできるようになります。
- Unity WebGLでは、メモリの操作は他のプラットフォームとは異なります。 最初に、プレーヤー設定でWebGLMemorySizeを指定する必要があります(デフォルトは256 MBです)。 ブラウザがアプリケーションにスペースを割り当てることができるように、割り当てられたメモリのサイズは事前にわかっている必要があります。 その後、バッファのサイズを変更できなくなります。 多くの場合、コンテンツは大量のメモリを消費し、最適な量を判断するには、アプリケーションをテストする必要があります。 Unity Profilerでこれを行うのが最善です。
- WebGLプロジェクトを開発するとき、必然的にテンプレートに出くわします。 Unityはデフォルトで、アプリケーションをロードするためのプログレスバーを備えたシンプルなHTMLページを提供し、カスタムテンプレートを実装することも可能にします。 アプリケーションが内部プリローダーを使用する場合(リソースのロード、サーバーへの接続など)、2つのプリローダーを順番に表示しないようにするには、テンプレートで使用可能なものに制限することをお勧めします。 Unity Loaderを介してアプリケーションをロードした後、ロードプロセスに関するイベントをテンプレートのJSメソッドに送信し、アプリケーションでテンプレートレイヤーを一時的に非表示にする必要があります。 これにより、プリローダーのテクスチャの複製を回避できます。
Plarium-Southの経験があなたのプロジェクトに新しい機会を開くことを願っています。