メインコンテンツまでスキップ

バンドルサイズとツリーシェイキング

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モデルを使うアプリケーションに必要なものを登録します。

main.js
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のデバッグビルドを使用するため、これらのエラーがログに出力されます。本番ビルドではリリースビルドが使用されます。

コンポーネントシステム​

アプリケーションが追加するコンポーネントの種類ごとに、そのコンポーネントシステムを登録します。その他に必要なものの列には、そのコンポーネントが使用する他のものを記載しています。

コンポーネントシステムコンポーネント用途その他に必要なもの
RenderComponentSystemrenderメッシュ、プリミティブ形状、glTFモデルのエンティティ
CameraComponentSystemcameraカメラ
LightComponentSystemlightディレクショナル、オムニ、スポット、エリアライト
ScriptComponentSystemscriptスクリプトスクリプトをscriptアセットとして読み込む場合はScriptHandler
GSplatComponentSystemgsplatガウシアンスプラットGSplatHandler
ParticleSystemComponentSystemparticlesystemパーティクルシステムパーティクルのテクスチャ用にTextureHandler
AnimComponentSystemanimアニメーションステートグラフとアニメーションレイヤーanimclipとanimstategraphアセットを読み込む場合はAnimClipHandlerとAnimStateGraphHandler
AnimationComponentSystemanimation従来のアニメーション再生(animに置き換えられました)AnimationHandler
ModelComponentSystemmodel従来のメッシュ(renderに置き換えられました)ModelHandler
SoundComponentSystemsoundサウンドの再生AudioHandler、およびAppOptionsのsoundManager
AudioListenerComponentSystemaudiolistener位置付きサウンドのリスナーAppOptionsのsoundManager
CollisionComponentSystemcollisionコリジョン形状とトリガーammo.js
RigidBodyComponentSystemrigidbody剛体物理CollisionComponentSystem、ammo.js
JointComponentSystemjoint物理ジョイントRigidBodyComponentSystem、CollisionComponentSystem、ammo.js
ScreenComponentSystemscreenユーザーインターフェイスのルート
ElementComponentSystemelementテキスト、画像、グループのエレメントScreenComponentSystem、テキスト用にFontHandler、入力用にAppOptionsのelementInput
ButtonComponentSystembuttonボタンElementComponentSystem、AppOptionsのelementInput
ScrollViewComponentSystemscrollviewスクロールするコンテンツElementComponentSystem、スクロールバー用にScrollbarComponentSystem
ScrollbarComponentSystemscrollbarスクロールバーElementComponentSystem
LayoutGroupComponentSystemlayoutgroup子エレメントのレイアウトElementComponentSystem
LayoutChildComponentSystemlayoutchildレイアウトグループ内のエレメントのレイアウト設定ElementComponentSystem、LayoutGroupComponentSystem
SpriteComponentSystemsprite2Dスプライトとスプライトアニメーションスプライトを読み込むためのSpriteHandler、TextureAtlasHandler、TextureHandler

リソースハンドラー​

アプリケーションが読み込むアセットの種類ごとに、そのリソースハンドラーを登録します。

リソースハンドラーアセットの種類読み込むもの
TextureHandlertexture画像、HDR画像、圧縮テクスチャ
ContainerHandlercontainerglTFとGLBのモデル(メッシュ、マテリアル、テクスチャ、アニメーションを含む)
ScriptHandlerscriptスクリプトを定義するJavaScriptファイル
GSplatHandlergsplatガウシアンスプラットのファイル
CubemapHandlercubemapキューブマップ
MaterialHandlermaterialJSONとして保存されたマテリアル
RenderHandlerrendercontainerアセットを参照するメッシュ(Editorからエクスポートされたもの)
FontHandlerfontテキストエレメント用のフォント
AudioHandleraudioサウンドファイル
AnimClipHandleranimclipanimコンポーネント用のアニメーションクリップ
AnimStateGraphHandleranimstategraphanimコンポーネント用のアニメーションステートグラフ
AnimationHandleranimation従来のanimationコンポーネント用のアニメーション
ModelHandlermodel従来のmodelコンポーネント用のモデル
SpriteHandlerspriteスプライト
TextureAtlasHandlertextureatlasスプライト用のテクスチャアトラス
SceneHandlersceneEditorからエクスポートされたシーン
JsonHandlerjsonJSONデータ
TextHandlertextテキストファイル
BinaryHandlerbinaryバイナリデータ(ArrayBufferとして)

その他のオプション​

AppOptionsのその他のプロパティも同じように機能を追加します。設定しなかったものは含まれません。

オプション値用途
graphicsDevicecreateGraphicsDeviceで作成したGraphicsDeviceレンダリング。必須です。
mousenew Mouse(canvas)app.mouseによるマウス入力の読み取り
touchnew TouchDevice(canvas)app.touchによるタッチ入力の読み取り
keyboardnew Keyboard(window)app.keyboardによるキーボード入力の読み取り
gamepadsnew GamePads()app.gamepadsによるゲームパッド入力の読み取り
elementInputnew ElementInput(canvas)ユーザーインターフェイスのエレメントに対するマウスとタッチの入力
soundManagernew SoundManager()soundとaudiolistenerコンポーネントによるサウンドの再生
lightmapperLightmapperクラス実行時のライトマップのベイク
batchManagerBatchManagerクラスメッシュインスタンスのバッチへの結合
xrXrManagerクラスapp.xrによるWebXR
assetPrefix文字列すべてのアセットのURLに付加されるプレフィックス
scriptPrefix文字列すべてのスクリプトのURLに付加されるプレフィックス
scriptsOrderスクリプトのURLの配列スクリプトを読み込む順序
devtoolstrueまたはfalsePlayCanvas Inspectorなどの開発者ツールにアプリケーションを通知するかどうか。デフォルトはtrueです。

各入力デバイスは、ここで設定しない限りアプリケーション上でnullのままです。

バンドルを小さく保つ​

  • playcanvasからインポートします。 パッケージ名は、ビルドツールがツリーシェイキングできるモジュール単位のビルドに解決されます。playcanvas/build/にある単一ファイルのビルドは、インポートマップからなど、ビルドツールを使わずに利用するためのものです。
  • エンジンのエクスポートを直接使用します。 名前付きインポート(import { Entity } from 'playcanvas')と名前空間インポートのメンバー(pc.Entity)は、どちらもツリーシェイキングされます。setup(pc)のように名前空間全体を値として関数に渡すと、esbuildなど一部のビルドツールはエンジン全体を残します。
  • バンドルの内容を確認します。 esbuildは--analyzeで各モジュールのサイズを出力し、rollup-plugin-visualizerはViteやRollupのバンドルのマップを描画します。