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

<pc-app>

<pc-app>タグは、PlayCanvas アプリケーションのルート要素です。PlayCanvas アプリケーションを初期化し、シーンのコンテナを提供するために使用されます。

使用法
  • ドキュメントの body 要素の子孫である必要があります。

属性​

属性タイプデフォルト説明
alphaBoolean"true"アプリケーションがフレームバッファにアルファチャネルを割り当てるかどうか。これにより、シーンが描画されていない部分でページが透けて見えます
antialiasBoolean"true"アプリケーションがアンチエイリアシングを使用するかどうか
area-light-lutsAsset ID-エリアライトのルックアップテーブルをJSONとして保持する<pc-asset>のID。これを読み込むとアプリケーション全体でエリアライトが有効になり、rect・disk・sphereのshapeを持つ<pc-light>要素が意図どおりに描画されます。外すと再び無効になります。即座に適用されます。エリアライトを参照
backendEnum"webgpu"グラフィックスエンジンのバックエンド: "webgpu" | "webgl2" | "null"。WebGPUが利用できないブラウザではWebGL 2にフォールバックします。WebGL 2を強制するには"webgl2"を設定してください。"null"は何も描画しないレンダラーを選択し、ヘッドレステスト用に存在します
depth-bufferBoolean"true"アプリケーションがデプスバッファを割り当てるかどうか
loading-barBoolean"true"起動時およびアセットのプリロード中に、アプリケーションが組み込みのローディングバーを表示するかどうか
max-pixel-ratioNumber上限なしアプリケーションがレンダリングするピクセル比の上限(0より大きい値)。キャンバスはこの値とディスプレイ自身のデバイスピクセル比のうち小さい方でサイズが決まります。したがって"1"はCSS解像度でレンダリングし、"2"は高密度ディスプレイのすべてのピクセルを描画することなく鮮明さを保ちます
physics-time-scaleNumber"1"物理シミュレーションが毎フレーム進める時間に掛かる倍率で、time-scaleに重ねて適用されます。1未満はスローモーション、1を超えると高速になり、"0"はアプリケーションの他の部分を動かしたまま物理を一時停止します。たとえば、ゲームの世界を止めたまま操作できる状態を保つ必要があるポーズメニューに使えます
pickingEnum"auto"エンティティ要素でポインターイベントをディスパッチするために、アプリケーションがポインターの下のシーンをいつピッキングするか: "auto" | "always" | "none"。autoは、あるイベントの種類のリスナーがエンティティ要素または<pc-scene>に登録されている間だけ、その種類についてピッキングします。alwaysはすべてのポインターイベントでピッキングします。ドキュメント上のリスナーや、ReactのonPointerMoveのようなフレームワークの委譲ハンドラーなど、アプリケーションが認識できないリスナーにはこれが必要です。noneはピッキングを一切行わないため、エンティティはポインターイベントを受け取りません。ピッキングではシーンをもう一度レンダリングするため、autoがデフォルトになっています。イベントがディスパッチされるタイミングを参照
stencil-bufferBoolean"true"アプリケーションがステンシルバッファを割り当てるかどうか
time-scaleNumber"1"アプリケーションが毎フレーム進める時間に掛かる倍率。スクリプト、アニメーション、物理はすべてこの倍率を掛けた時間で進むため、1未満はスローモーション、1を超えると高速になり、"0"はシーンの描画を続けたまま3つすべてをまとめて一時停止します。物理だけを遅くしたり一時停止したりするにはphysics-time-scaleを使用してください
with-credentialsBoolean"false"アセットのリクエストが他のオリジンに資格情報(CookieとHTTP認証)を送信するかどうか。アセットサーバー側でCORSにより許可されている必要があります。エンジンはこの設定をページ全体で共有されるHTTPクライアントに保持するため、ページ上のすべての<pc-app>に適用されます。この属性を付けて起動したアプリはすべてのアプリケーションで有効にし、その後いずれかのアプリで変更すると、すべてのアプリケーションに対して設定されます
属性が読み取られるタイミング

alpha・antialias・backend・depth-buffer・stencil-bufferはグラフィックスデバイスを設定する属性なので、要素がドキュメントに挿入されてグラフィックスデバイスを作成する際に一度だけ読み取られます。その後に変更しても、要素のプロパティは更新されますが実行中のアプリケーションには影響せず、その旨の警告がログに出力されます。新しい値を適用するには、要素を削除して再挿入してください。

それ以外の属性はすべてライブで、変更すると実行中のアプリケーションにすぐ適用されます。ただし、loading-barはバーを取り除くことしかできません(ローディングバーを参照)。2つのタイムスケールは、どのスクリプトのinitialize()よりも前に設定されます。

サイズ指定​

この要素は<video>や<img>のような置換要素と同じ方式でサイズが決まります。つまり、ページのCSSが制御するブロックレベルのボックスで、デフォルトはキャンバスの固有サイズである300×150ピクセルです。アプリケーションのキャンバスは常に要素全体を満たし、描画バッファの解像度は要素のサイズにライブで追従します(上限はmax-pixel-ratio)。スプリッターのドラッグ、フレックスのリフロー、CSSアニメーションなど、要素のサイズを変えるものすべてにレンダリング結果が追従します。

フルスクリーンは組み込みの動作ではなく、通常のCSSで実現します。

pc-app {
width: 100%;
height: 100vh; /* 動的ビューポート単位に未対応のブラウザ向けフォールバック */
height: 100dvh;
}

同様に、要素はカード、分割ペイン、グリッドセルなど、任意のサイズで埋め込むことができ、1つのページに複数のアプリを共存させることもできます。

明示的な寸法でサイズを指定する

要素のサイズは明示的なwidthとheightで指定してください。ライブラリのデフォルトスタイルが明示的な寸法を与えており、CSSのボックス解決では明示的な寸法がinsetによる引き伸ばしより優先されるため、position: fixed; inset: 0だけでは要素は引き伸ばされません。(デフォルトは:where()により詳細度ゼロで宣言されているため、どんなに単純なページ側のルールでも上書きできます。)

描画バッファは要素だけでなくディスプレイにも追従します。ウィンドウを画素密度の異なる画面に移動したり、ページをズームしたりすると、要素のサイズが変わらなくてもデバイスピクセル比が変わるため、アプリケーションはピクセル比を評価し直し、それに合わせてバッファのサイズを変更します。実際に使われる比率、つまりmax-pixel-ratioとディスプレイ自身の比率の小さい方はapp.graphicsDevice.maxPixelRatioに入り、要素のmaxPixelRatioプロパティは上限値を返します。描画品質を管理するコードは、app.graphicsDevice.maxPixelRatioに直接代入することもできます。その場合、ディスプレイが変わってもその比率は保たれ、バッファのサイズだけが追従します。max-pixel-ratioを再び設定すると、比率の管理は要素に戻ります。

要素のサイズが描画バッファを制御しない唯一の例外はXRセッションの表示中で、その間はセッションがバッファを所有します。

ローディングバー​

アプリケーションの起動中およびアセットのプリロード中、<pc-app>は要素の上端にローディングバーを表示します。表示を抑制するにはloading-bar="false"を設定するか(起動後に設定するとバーは直ちに消えますが、"true"に戻しても要素を再挿入するまで効果はありません)、次のCSSカスタムプロパティでテーマを設定します。

プロパティ説明
--pc-loading-bar-colorバーの塗りつぶされた部分の色
--pc-loading-bar-backgroundその背後にある未塗りつぶしのトラックの色
--pc-loading-bar-heightバーの高さ

独自のローディング画面を作成する場合は、バーを抑制し、要素のprogressイベントとloadProgressプロパティから制御してください。

イベント​

これらのイベントは、addEventListener()を使用するか、このインターフェースのoneventnameプロパティにイベントリスナーを割り当てることでリッスンできます。

イベント説明
progressアプリケーションがアセットをプリロードしている間に発生するProgressEvent。loadedとtotalはバイト数ではなくアセット数で、読み込みに失敗したアセットも読み込み済みとして数えられます。起動ごとに少なくとも1回発生し、最後のイベントでは必ずloadedがtotalと等しくなります。
errorグラフィックスデバイスを作成できず、アプリケーションが起動できないとき(WebGLが無効化されている、GPUがブロックリストに載っているなど)に発生するErrorEvent。messageには要求されたバックエンドの名前が入り、errorには元の失敗が入ります。捕捉する方法は下記を参照してください。

どちらのイベントもバブリングしないため、要素自身でリッスンしてください。

起動の失敗を処理する​

errorを発生させた要素は決してready状態にならず、appプロパティはnullのままです。特に、whenReady('pc-app')は永遠に解決しません(プログラムによるアクセスを参照)。フォールバックUIを表示したいページは、準備完了を待つのではなく、このイベントをリッスンしてください。ハンドラーはインライン属性として設定します。失敗はライブラリが起動した直後、自分のモジュールスクリプトが実行される前に報告されることがあるため、モジュールスクリプトから追加したリスナーでは取りこぼす可能性があります。属性であれば、要素が解析された時点から有効です。

<pc-app onerror="document.getElementById('fallback').hidden = false">

このイベントは、デバイスをまったく作成できない場合を対象としています。デフォルトのbackendでは、WebGPUを提供するブラウザはまずWebGPUを試してからWebGL 2にフォールバックしますが、その経路で両方が失敗すると、現在のエンジンはerrorを発生させずに要素を待機状態のままにします。必ず表示すべきフォールバックには、タイムアウトも設けてください。数秒経っても要素がready状態にならなければ表示します。

要素を削除して再挿入すると、その時点の属性で起動を再試行します。

エンティティでディスパッチされたポインターイベントも、キャンバス自身のネイティブなポインターイベントと並んで<pc-app>までバブリングします。両者はevent.isTrustedで区別できます。ブラウザのネイティブなイベントではtrue、ディスパッチされたイベントではfalseです。エンティティのイベントがそもそもディスパッチされるかどうかはpickingによって決まります。イベントがディスパッチされるタイミングを参照してください。

例​

カメラ、ライト、球体からなる完全なアプリケーションです。<pc-app>タグに antialias="false" や max-pixel-ratio="1" を設定してみましょう:

ライブサンプル
<pc-app>
<pc-scene>
<pc-entity name="camera" position="0 0 3">
<pc-camera clear-color="#8099e6"></pc-camera>
</pc-entity>
<pc-entity name="light" rotation="45 45 0">
<pc-light></pc-light>
</pc-entity>
<pc-entity name="ball">
<pc-render type="sphere"></pc-render>
</pc-entity>
</pc-scene>
</pc-app>

JavaScriptインターフェース​

AppElement APIを使用して、<pc-app>要素をプログラムで作成および操作できます。

appプロパティは、実行中のエンジンのAppBaseです。要素の準備が完了するまではnullで、シーン、アセットレジストリ、レンダーループにアクセスできます。elementFromEntity()は、エンジンのエンティティからそれを表す要素を返します。

関連項目​

  • <pc-scene> — アプリがレンダリングする唯一のシーン
  • <pc-asset> — シーンが始まる前にアプリがプリロードするリソース
  • <pc-wasm> — 物理などアプリが起動前にロードするモジュール
  • プログラムによるアクセス — JavaScriptからreadyを待ち、appにアクセスする方法

サンプル: Spinning Cube、Basic Shapes