<pc-node>
<pc-node>タグは、<pc-model>がインスタンス化した階層内のノードにバインドし、それに対するオーバーライドを宣言します。GLBを編集することなく、GLBがオーサリングされた内容を調整するための手段です。ノードを非表示にする、移動する、コンポーネントを与える、その下に新しいコンテンツを親子付けする、といったことができます。
<pc-entity>がエンティティを作成するのに対し、<pc-node>はモデルがすでに作成したエンティティを参照します。そのnameは常に検索キーであり、名前の変更ではありません。
<pc-model>の子孫である必要があります。直接の子か、別の<pc-node>の内側にネストされている必要があります。- 0からn個のネストされた
<pc-node>の子を持つことができます。それらは自身のnameを、バインドされたノードのサブツリー内で解決します。 - 0からn個の
<pc-entity>の子を持つことができます。それらは作成され、バインドされたノードの下に親子付けされます — 新しいコンテンツのアタッチポイントです。 <pc-entity>と同じコンポーネントタグ —<pc-collision>、<pc-light>、<pc-scripts>など — を持つことができます。それらはバインドされたノードにそのコンポーネントを追加します。
属性
| 属性 | タイプ | デフォルト | 説明 |
|---|---|---|---|
enabled | Boolean | オーサリング値 | ノードの有効状態をオーバーライドします |
index | Number | - | nameが複数のノードに一致する場合にバインドする一致項目。深さ優先順で0から始まります。名前が曖昧な場合は必須で、それ以外の場合は省略可能です |
name | String | - | バインドするノードの名前。囲んでいる<pc-model>(または<pc-node>)内で検索されます |
position | Vector3 | オーサリング値 | ノードのローカル位置を「X Y Z」値でオーバーライドします |
rotation | Vector3 | オーサリング値 | ノードのローカル回転を度単位の「X Y Z」オイラー角でオーバーライドします |
scale | Vector3 | オーサリング値 | ノードのローカルスケールを「X Y Z」値でオーバーライドします |
tags | String | オーサリング値 | ノードのタグをオーバーライドします。スペースまたはカンマで区切ります |
nameとindexを除くすべてはオーバーライドであるため、<pc-node>は存在しない属性を他のどのタグとも異なる形で解釈します。存在する属性はオーサリング値を置き換え、存在しない属性はそれをそのまま残します。実行時に属性を削除する(または対応するJavaScriptプロパティにnullを代入する)と、エンジンのデフォルト値ではなく、モデルがオーサリングされた値が復元されます。上の表に具体的なデフォルト値がないのはこのためです。デフォルト値とは、GLBが持つ値そのものです。
オーバーライドはオーサリング値を置き換えるものであり、それと合成されるわけではありません。position="0 1 0"は、エクスポート時の値が何であれ、ノードをローカルYの1に配置します。
ノードの検索
nameは読み込まれた階層内のノード名に対して照合し、深さ優先順で最初に一致したものを採用します。<pc-node>を別の<pc-node>の内側にネストすると、内側の検索は外側のノードのサブツリーに限定されます。名前がローカルにしか一意でないノードに到達する、最も簡単な方法です。
検索範囲内で名前が一意でない場合、要素は何もバインドせず、すべての候補のパスを示す警告を出力します。これによりindexで1つを選択できます。
pc-node 'Wheel' is ambiguous in model 'car' - specify index: [0] Body/Wheel_FL/Wheel, [1] Body/Wheel_FR/Wheel
何もバインドしないのは意図的な設計です。推測すれば誤ったノードを黙って装飾してしまい、再エクスポートによって名前の重複が生じた際に、これまで動作していたドキュメントが壊れてしまいます。
その他の解決失敗も同じように警告します。何にも一致しない名前(タイプミスのヒントとして、見つかった中で最も近い名前を添えます)、一致数を超えるindex、そして別の<pc-node>がすでにバインドしているノードです。いずれの場合も要素は何もバインドせず、readyになることはありません。
要素はバインドされて初めてreadyになり、その子孫も一緒に待機します。モデルが再読み込みされた場合、またはnameを変更して要素のターゲットが変わった場合、要素は再解決し、オーバーライド・コンポーネント・アタッチされたコンテンツを新しいノードに対して再適用します。
イベント
<pc-node>は<pc-entity>と同じポインターイベントをディスパッチします。ポインターがバインドされたノードのジオメトリと交差したときに発生します。ノードをバインドすることがそれをピック対象にするため、<pc-node>はモデルの一部をインタラクティブにする手段でもあります。
| イベント | 説明 |
|---|---|
pointerdown | ポインターがノード上で押下されたときに発生します。 |
pointerenter | ポインターがノードに入ったときに発生します。 |
pointerleave | ポインターがノードを離れたときに発生します。 |
pointermove | ポインターがノード上で移動したときに発生します。 |
pointerup | ポインターがノードから解放されたときに発生します。 |
インラインのonpointer*属性は、<pc-entity>とまったく同じように動作します。
例
<pc-app>
<pc-asset src="assets/car.glb" id="car"></pc-asset>
<pc-scene>
<pc-entity name="camera" position="0 1 4">
<pc-camera></pc-camera>
</pc-entity>
<pc-model asset="car">
<!-- GLBに含まれていた地面プレーンを非表示にします -->
<pc-node name="Plane" enabled="false"></pc-node>
<!-- ルーフを少し持ち上げてタグを付けます。オーサリングされた回転とスケールはそのままです -->
<pc-node name="Roof" position="0 0.05 0" tags="openable"></pc-node>
<!-- ヘッドライトノードの下にスポットライトをアタッチします -->
<pc-node name="Headlight_L">
<pc-entity>
<pc-light type="spot" intensity="4" range="20"></pc-light>
</pc-entity>
</pc-node>
</pc-model>
</pc-scene>
</pc-app>
JavaScriptインターフェース
NodeElement APIを使用して、<pc-node>要素をプログラムで作成および操作できます。
バインドしたノードを返すentityに加えて、この要素は解決の結果を報告します。stateは、バインドするものがまだない間(nameが未設定、またはモデルがインスタンス化されていない)は"pending"、バインドされると"bound"、解決が失敗した場合は"missing"、"ambiguous"、"duplicate"のいずれかになります。pathは検索範囲以下のバインドされたノードの/区切りのパスで、バインドされていない間はnullです。これらを組み合わせることで、コンソールを読む代わりに、ドキュメントのバインディングをプログラムで検証できます。
import { whenReady } from '@playcanvas/web-components';
const node = await whenReady('pc-node[name="Roof"]');
console.log(node.state, node.path); // 'bound' 'Body/Roof'