バンドルサイズとツリーシェイキング
PlayCanvas Engineは、ソースファイルごとに1つのモジュールに分かれたESモジュールとしてnpmで公開されており、そのpackage.jsonは"sideEffects": falseを宣言しています。Vite、Rollup、esbuild、webpackなどのビルドツールでアプリケーションをバンドルすると、ビルドツールはコード内のインポートをたどり、何からも使われていないモジュールをすべて除外します。これをツリーシェイキングと呼びます。
バンドルに含まれる内容の大部分は、AppBaseの設定方法によって決まります。このページでは、アプリケーションが使用するものだけを含めるための設定方法を説明します。
仕組み
コードでは、コンポーネントやアセットを名前で参照します。たとえばentity.addComponent('render')やnew Asset('logo', 'texture', { url })です。ビルドツールは、これらの文字列からアプリケーションがエンジンのどの部分を必要とするかを判断できません。
そのためAppBaseは、AppOptionsオブジェクトに列挙したコンポーネントシステムとリソースハンドラーだけを登録します。
- コンポーネントシステムは、1種類のコンポーネントを実行します。たとえば、
RenderComponentSystemはrenderコンポーネントを実行します。 - リソースハンドラーは、1種類のアセットを読み込みます。たとえば、
TextureHandlerはtextureアセットを読み込みます。
列挙したクラスはコードからインポートされるため、バンドルに含まれます。列挙しなかったクラスは、そのクラスだけが使用するコードと一緒に除外されます。
AppBaseの設定
この例では、メッシュ、カメラ、ライト、スクリプト、テクスチャ、glTFモデルを使うアプリケーションに必要なものを登録します。
import {
AppBase,
AppOptions,
CameraComponentSystem,
ContainerHandler,
createGraphicsDevice,
DEVICETYPE_WEBGPU,
Keyboard,
LightComponentSystem,
Mouse,
RenderComponentSystem,
ScriptComponentSystem,
ScriptHandler,
TextureHandler,
TouchDevice
} from 'playcanvas';
const canvas = document.getElementById('application');
const device = await createGraphicsDevice(canvas, {
deviceTypes: [DEVICETYPE_WEBGPU]
});
const createOptions = new AppOptions();
createOptions.graphicsDevice = device;
// input devices the application reads
// アプリケーションが読み取る入力デバイス
createOptions.mouse = new Mouse(canvas);
createOptions.touch = new TouchDevice(canvas);
createOptions.keyboard = new Keyboard(window);
// component systems and resource handlers the application uses
// アプリケーションが使用するコンポーネントシステムとリソースハンドラー
createOptions.componentSystems = [
RenderComponentSystem,
CameraComponentSystem,
LightComponentSystem,
ScriptComponentSystem
];
createOptions.resourceHandlers = [TextureHandler, ContainerHandler, ScriptHandler];
const app = new AppBase(canvas);
app.init(createOptions);
app.start();
システムを登録せずにそのコンポーネントを使用すると、addComponentはnullを返し、EngineのデバッグビルドはaddComponent: System 'sound' doesn't existをログに出力します。ハンドラーを登録せずにアセットを読み込むと、No resource handler for asset typeで読み込みが失敗します。
開発中、Viteなどdevelopmentエクスポート条件を設定するビルドツールはEngineのデバッグビルドを使用するため、これらのエラーがログに出力されます。本番ビルドではリリースビルドが使用されます。
コンポーネントシステム
アプリケーションが追加するコンポーネントの種類ごとに、そのコンポーネントシステムを登録します。その他に必要なものの列には、そのコンポーネントが使用する他のものを記載しています。
| コンポーネントシステム | コンポーネント | 用途 | その他に必要なもの |
|---|---|---|---|
RenderComponentSystem | render | メッシュ、プリミティブ形状、glTFモデルのエンティティ | |
CameraComponentSystem | camera | カメラ | |
LightComponentSystem | light | ディレクショナル、オムニ、スポット、エリアライト | |
ScriptComponentSystem | script | スクリプト | スクリプトをscriptアセットとして読み込む場合はScriptHandler |
GSplatComponentSystem | gsplat | ガウシアンスプラット | GSplatHandler |
ParticleSystemComponentSystem | particlesystem | パーティクルシステム | パーティクルのテクスチャ用にTextureHandler |
AnimComponentSystem | anim | アニメーションステートグラフとアニメーションレイヤー | animclipとanimstategraphアセットを読み込む場合はAnimClipHandlerとAnimStateGraphHandler |
AnimationComponentSystem | animation | 従来のアニメーション再生(animに置き換えられました) | AnimationHandler |
ModelComponentSystem | model | 従来のメッシュ(renderに置き換えられました) | ModelHandler |
SoundComponentSystem | sound | サウンドの再生 | AudioHandler、およびAppOptionsのsoundManager |
AudioListenerComponentSystem | audiolistener | 位置付きサウンドのリスナー | AppOptionsのsoundManager |
CollisionComponentSystem | collision | コリジョン形状とトリガー | ammo.js |
RigidBodyComponentSystem | rigidbody | 剛体物理 | CollisionComponentSystem、ammo.js |
JointComponentSystem | joint | 物理ジョイント | RigidBodyComponentSystem、CollisionComponentSystem、ammo.js |
ScreenComponentSystem | screen | ユーザーインターフェイスのルート | |
ElementComponentSystem | element | テキスト、画像、グループのエレメント | ScreenComponentSystem、テキスト用にFontHandler、入力用にAppOptionsのelementInput |
ButtonComponentSystem | button | ボタン | ElementComponentSystem、AppOptionsのelementInput |
ScrollViewComponentSystem | scrollview | スクロールするコンテンツ | ElementComponentSystem、スクロールバー用にScrollbarComponentSystem |
ScrollbarComponentSystem | scrollbar | スクロールバー | ElementComponentSystem |
LayoutGroupComponentSystem | layoutgroup | 子エレメントのレイアウト | ElementComponentSystem |
LayoutChildComponentSystem | layoutchild | レイアウトグループ内のエレメントのレイアウト設定 | ElementComponentSystem、LayoutGroupComponentSystem |
SpriteComponentSystem | sprite | 2Dスプライトとスプライトアニメーション | スプライトを読み込むためのSpriteHandler、TextureAtlasHandler、TextureHandler |
リソースハンドラー
アプリケーションが読み込むアセットの種類ごとに、そのリソースハンドラーを登録します。
| リソースハンドラー | アセットの種類 | 読み込むもの |
|---|---|---|
TextureHandler | texture | 画像、HDR画像、圧縮テクスチャ |
ContainerHandler | container | glTFとGLBのモデル(メッシュ、マテリアル、テクスチャ、アニメーションを含む) |
ScriptHandler | script | スクリプトを定義するJavaScriptファイル |
GSplatHandler | gsplat | ガウシアンスプラットのファイル |
CubemapHandler | cubemap | キューブマップ |
MaterialHandler | material | JSONとして保存されたマテリアル |
RenderHandler | render | containerアセットを参照するメッシュ(Editorからエクスポートされたもの) |
FontHandler | font | テキストエレメント用のフォント |
AudioHandler | audio | サウンドファイル |
AnimClipHandler | animclip | animコンポーネント用のアニメーションクリップ |
AnimStateGraphHandler | animstategraph | animコンポーネント用のアニメーションステートグラフ |
AnimationHandler | animation | 従来のanimationコンポーネント用のアニメーション |
ModelHandler | model | 従来のmodelコンポーネント用のモデル |
SpriteHandler | sprite | スプライト |
TextureAtlasHandler | textureatlas | スプライト用のテクスチャアトラス |
SceneHandler | scene | Editorからエクスポートされたシーン |
JsonHandler | json | JSONデータ |
TextHandler | text | テキストファイル |
BinaryHandler | binary | バイナリデータ(ArrayBufferとして) |
その他のオプション
AppOptionsのその他のプロパティも同じように機能を追加します。設定しなかったものは含まれません。
| オプション | 値 | 用途 |
|---|---|---|
graphicsDevice | createGraphicsDeviceで作成したGraphicsDevice | レンダリング。必須です。 |
mouse | new Mouse(canvas) | app.mouseによるマウス入力の読み取り |
touch | new TouchDevice(canvas) | app.touchによるタッチ入力の読み取り |
keyboard | new Keyboard(window) | app.keyboardによるキーボード入力の読み取り |
gamepads | new GamePads() | app.gamepadsによるゲームパッド入力の読み取り |
elementInput | new ElementInput(canvas) | ユーザーインターフェイスのエレメントに対するマウスとタッチの入力 |
soundManager | new SoundManager() | soundとaudiolistenerコンポーネントによるサウンドの再生 |
lightmapper | Lightmapperクラス | 実行時のライトマップのベイク |
batchManager | BatchManagerクラス | メッシュインスタンスのバッチへの結合 |
xr | XrManagerクラス | app.xrによるWebXR |
assetPrefix | 文字列 | すべてのアセットのURLに付加されるプレフィックス |
scriptPrefix | 文字列 | すべてのスクリプトのURLに付加されるプレフィックス |
scriptsOrder | スクリプトのURLの配列 | スクリプトを読み込む順序 |
devtools | trueまたはfalse | PlayCanvas Inspectorなどの開発者ツールにアプリケーションを通知するかどうか。デフォルトはtrueです。 |
各入力デバイスは、ここで設定しない限りアプリケーション上でnullのままです。
バンドルを小さく保つ
playcanvasからインポートします。 パッケージ名は、ビルドツールがツリーシェイキングできるモジュール単位のビルドに解決されます。playcanvas/build/にある単一ファイルのビルドは、インポートマップからなど、ビルドツールを使わずに利用するためのものです。- エンジンのエクスポートを直接使用します。 名前付きインポート(
import { Entity } from 'playcanvas')と名前空間インポートのメンバー(pc.Entity)は、どちらもツリーシェイキングされます。setup(pc)のように名前空間全体を値として関数に渡すと、esbuildなど一部のビルドツールはエンジン全体を残します。 - バンドルの内容を確認します。 esbuildは
--analyzeで各モジュールのサイズを出力し、rollup-plugin-visualizerはViteやRollupのバンドルのマップを描画します。