Capacitorを使用することで、WebアプリをiOS/Android向けにビルドすることができます。
今回はCocosCreatorで制作したWebアプリをCapaitorを経由してiOS/Android向けにビルドしてみました。Capacitor自体はじめて利用します。
React・VueなどのコンポーネントやNext.jsなどの主要なWebフレームワークであればCapacitorを利用した例や情報など豊富にありそうですが、CocosCreatorについては案の定まったく情報がありません。
といってもCapacitorはあらゆるWebアプリに対応しているので手順自体はドキュメント通りで基本的に問題ありませんでした。一部つまづいたところがあるため記事の中に書いていきます。
目次
Cocosの標準iOS/Androidビルド
Cocosはモバイル特化のエンジンなので、エンジン本体のみでもiOS/Androidビルドに対応しています。
通常のiOS/Androidビルドを使用することでパフォーマンスにシビアなところでC++コードが使用されたり、iOSはMetal、AndroidはVulkan/OpenGLESなどのグラフィックスライブラリが利用できます。
Capacitorを経由したビルドはWebView/WebGLでの実行になるためパフォーマンス的にはより厳しくなり、グラフィック表現の自由度も減ります。
そのため基本的には通常のiOS/Androidビルドを使用するのが無難ではあるのですが、アセットの中にはiOS/Androidビルドに対応していないものもあります。
今回はストアで購入できるTextMeshProなしでアプリを作ることが難しそうで、Webのみ対応だった点からCapacitorを試してみました。
パフォーマンス的にはもともとWeb版でも十分に動作する範囲で作ることを考えていたので、今回はあまり気にしていません。
環境構築
セットアップ
ドキュメント通りにセットアップします。
CocoaPodsはインストール済みのものが動かなかったのでHomebrewで入れ直しました。
Capacitorのインストール
ドキュメントを参考にインストールしていきます。
今回はCocosプロジェクトの中にcapacitor用のディレクトリを作成し、その中に「debug」と「release」で分けて2つcapacitorプロジェクトを作成してみました。それぞれappIdなど別のものにしたいためです。
project
├ assets
├ build
├ …色々…
└ capacitor(作成)
以下のコマンドで新しいcapacitorプロジェクトの作成と設定を行います。
npm init @capacitor/app
作成されたディレクトリに移動し、iOS/Androidのプロジェクトを作成します。
npm i @capacitor/android @capacitor/ios
srcフォルダはいらないので削除してもOK。
ここでcapacitor.config.jsonを開いてwebDirの項目を「dist」から以下のような感じでCocosのビルド結果を参照するように変更します。
{
...
"webDir": "../../build/web-mobile",
ここで設定したとおりのディレクトリ名でCocosのweb-mobileビルドを実行しておきます。
以下のコマンドでiOS/Androidのプロジェクトを生成します。
npx cap add android
npx cap add ios
今後CocosのWebビルドを更新した際は、以下のコマンドでCapacitor側へ同期できます。
npx cap sync
ビルドの準備はこれで完了です。あとはここからCapacitorが生成したiOS/Androidプロジェクトそれぞれに対してアプリアイコンの設定などが必要です。
Androidビルド
以下のコマンドでAndroidStudioを開きます。あとはAndroidStudioから実機テストやapk、aabの出力などが可能です。
npx cap open android
iOSビルド
iOSはひと手間あり、Cocosから出力されたディレクトリ直下のindex.htmlの以下の部分を変更します。
index.js実行時にエラーが発生したらログ出力してくれる部分ですが、iOSのWebViewでは動かずエラーになる様子だったため普通のjs読み込みに置き換えました。
この作業の自動化については後述します。
あとはAndroidと同様に以下のコマンドでXcodeを開き、シミュレータや実機でテストできます。
npx cap open ios
index.jsロード置き換えの自動化
上記のエラーが出るindex.jsロードの根本原因となるファイルを修正して置き換えられるのがベストですが、ひとまずindex.htmlの書き換えを手動で行わなくていいようにテンプレートを修正します。
ビルドテンプレートについてのドキュメントはこちら。
まだCocosでweb-mobileビルドのテンプレートを作成していない場合は「Project > Create Build Template > Web Mobile」で作成します。
build-templates/web-mobile以下にindex.ejsが作成されるので、以下のようにcocosTemplateを読み込んでいるところを書き換えます。
これはこちらのindex-plugin.ejsというファイルの最後のindex.js読み込みだけ書き換えたものになります
index-plugin.ejs自体を修正できたらいいですが、このファイルをビルドテンプレート内に配置するとそのままビルド時にファイルとして出力されてしまうためindex.ejs側の修正で対応しました。
なおCapacitor用のビルドも通常のWebビルドもどちらもweb-mobileを使うため、同じ修正がWeb版にも入ってしまう問題はあります。
今回は特に気にしないことにしましたが、もしweb-desktopの方を使わないのであればweb-mobile用のテンプレートをごっそりweb-desktopのビルドテンプレートへもっていき、web-mobileはCapacitor専用とすることもできるかもしれません。
ただしweb-desktopはVConsoleがない等、web-mobileと同じというわけではないので微妙な方法ではあります。同じビルド種類でも別々のテンプレートを採用するようなことが可能であればベストですね。
(追記)CocosCreator3.8.3から、同じビルド種類に対して複数のテンプレートを用意できるようになったようです
CocosでCapacitorを併用するメリット・デメリット
今のところ認識しているものは以下のとおりです。
Capacitorのメリット
ネイティブプラグインが充実している
公式から有志によるものまで、iOS/Androidネイティブ機能を呼び出すためのプラグインが充実しています。
CocosCreatorはcocos2d-xと比べてWebに重きを置いているため、ネイティブ対応はかなり弱い印象です。Capacitorを併用することでそこを補えるような気がしています。
反面Cocosで既に対応されているものについては対応コストが増えてしまうというデメリットもありそうです。例えばSafeAreaコンポーネントは動作しなかったので以下のCapacitorプラグインでの対応してみました。
ブラウザやPWAではcssの「safe-area-inset-top」等で対応できるのですが、CapacitorでビルドしたアプリについてはiOSでは動作するのですがAndroidでは動作しなかったため、プラグインでの対応が必要でした。
公式プラグインではありませんが、導入してサンプルコード通りですぐに動いたので助かりました。Webブラウザで実行した場合は0が返ってくるようになっています。
注意点としては今回のインストール例であればCocosプロジェクト、debug/releaseのcapacitorプロジェクトそれぞれにプラグインのインストールが必要です。
これは少し手間ではあるので、debug/releaseのように分けなくても良い場合、あるいはappIdの設定などはビルドスクリプトで自動化する等で、Cocosプロジェクト内にCapacitorをインストールするのが楽かもしれません。
(2023/12/04 追記) Capacitorのドキュメントに環境設定を複数作成する方法が書かれていました。こちらを設定するのが良さそうです。
情報を入手しやすい
世界的に利用されているため、中国利用がメインのCocosの情報を探すよりは簡単そうです。
実装を共通化できる
Web向け実装をiOS/Androidビルドにも共通して利用できます。Cocosのテストは基本ブラウザで行うため、そこで動作していればCapacitorを経由したiOS/Androidビルドでも基本的には問題なく動作することが期待できるため、デバッグが楽になりそうです。
冒頭に書いたとおりWebのみ対応のアセットやOSSも利用できます。
HTML/CSSを利用できる
Cocosではビルド時にVConsoleというものを含めることができますが、ブラウザ向けのデバッガなので通常のiOS/Androidネイティブビルドでは動作しません。
Capacitorならこれも利用できるので、結構便利そうです。
また、試してはいませんがUIのみReactやVueなどを利用して3D表示にCocosを利用するなど、Webフレームワークを組み合わせたアプリを作ることも可能かと思われます。ただこれはCocosエディタからブラウザ実行した時にも動いてくれないと困るので、そのようなワークフローを構築できるかどうか次第ではあります。
→ 作成してみました。Vueはビルド後にエラーが出てしまうため諦めて、Reactで作成しました。
アプリサイズを削減できる
Cocosの通常ビルドでもUnity等と比べると十分に小さいですが、とりあえずAndroidでは通常ビルドと比べて半分くらいになりました。
ビルド時間が短い
Unity等のIL2CPP工程のある環境と比べたらCocosの通常ビルドでも十分速いですが、Capacitorのネイティブビルドはプラグインの追加などがなければWebアプリ部分のファイル更新だけなので、CocosのWebビルドと「npx cap sync」の実行だけで変更をすぐに実機テストできます。
Capacitorのデメリット
パフォーマンス的にシビアになる点を除くと以下のようなものがありそうです。
iOSで機能制約を受ける
Androidと比べてiOSのWebViewは、経験上Safari本家と比べて機能制約を受けやすいです。
基本的には問題なく動作すると思いますが、Safariで実行したときは動いていたものがiOSビルドでは動かないということはあるかもしれません。
iOSでFPSが安定しない
Androidでは処理時間が追いついていれば問題なく60fpsで安定するのですが、iOSは処理時間的に余裕でも56〜60fpsくらいの間でブレてしまいました。
ただこれはSafariでも発生したので、ネイティブビルド固有の問題ではなさそうです。以前はSafariでも発生していなかったので色々いじってるうちに発生したバグかも。
Webとネイティブで処理の切り分けは必要
SafeAreaのようなものであれば問題ないですが、ネイティブ機能によってはWebから実行してはいけないようなケースもあると思います。
Cocosのビルドであれば「cc/env」から実行環境を取得できますが、Capacitorを経由する場合はいずれもWebの扱いになってしまいます。
といってもCapacitorのコアに機能として用意されているので、こちらを使用すれば大丈夫そうです。
まとめ
インストールからビルドまで、とても簡単にできるようになっていて良いなと感じました!プラグイン連携など、大変なのはここからかと思いますが…笑
ネイティブビルドに重きを置くのであれば、そもそもCocosではなくUnityを使った方が何かと困らずパフォーマンスの限界を攻めたりグラフィック表現の追求もしやすいと思います。
Cocosを使うときはWebアプリを前提として、Capacitorを併用するというのは結構アリなのではないかという印象です。
現在開発中のアプリはまずWeb版を完成させてからiOS/Androidアプリ版を制作予定なので後になって大変な思いをするかもしれませんが、Capacitorの利用を前提として進めてみようと思います。
CocosCreatorの開発情報は以下の記事に引き続きまとめていきます。