今回は「ワールド内にいるプレイヤーの位置などの情報を取得・操作できる」機能を使ったアイテムの作成方法を紹介します。
この機能を使って、「当アバターの移動についてくる床」をつくります。

サンプルコード
空のGameObjectに「Movable Item」「Scriptable Item」の各コンポーネントを追加します。
Movable Itemと同時に追加される「Rigidbody」コンポーネントの「Is Kinematic」にチェックをつけておいてください。
見た目となる3Dモデルや上に乗るための足場のコライダーに加えて、アバターが乗っていることを検知するためのコライダーを追加します。
足場の上に0.1mほどの高さのコライダーオブジェクトを追加し、「Overlap Detector Shape」コンポーネントを追加してください。

アイテムの設定ができたら、Scriptable Itemコンポーネントに以下のスクリプトを設定します。
$.onUpdate(deltaTime => {
// 初期化
if (!$.state.initialized) {
$.state.initialized = true;
$.state.followingPlayer = null;
}
// 追跡中のプレイヤーを取得
let followingPlayer = $.state.followingPlayer;
// 乗っているプレイヤーをすべて取得
// 重なっているすべてのオブジェクトを取得し、そこからプレイヤーを抽出
let overlapPlayers = $.getOverlaps().map(overlap => overlap.handle).filter(handle => handle != null && handle.type === "player");
// ひとりも乗っていない場合は追跡しない
if (overlapPlayers.length == 0) {
$.state.followingPlayer = null;
return;
}
// 追跡中のプレイヤーがいない場合、乗っているプレイヤーのうちひとりを追跡中にする
if (followingPlayer == null || !followingPlayer.exists()) {
followingPlayer = overlapPlayers[0];
}
// 追跡中のプレイヤーが継続して乗っていれば、その位置に合わせてアイテムを移動
if (overlapPlayers.some(player => player.id == followingPlayer.id)) {
let position = $.getPosition();
let followingPosition = followingPlayer.getPosition();
$.setPosition(new Vector3(followingPosition.x, position.y, followingPosition.z));
}
// 追跡中のプレイヤーが降りていれば追跡をやめる
else {
followingPlayer = null;
}
// 追跡中のプレイヤーを更新
$.state.followingPlayer = followingPlayer;
});ワールドまたはアイテムとしてアップロードし、確認してみましょう。
アバターが上に乗って移動するとついてくるようになります。ジャンプして検出用のコライダーから離れると動かなくなります。

サンプルコードの解説
新しい機能を利用している部分を中心に、サンプルコードを解説します。
let overlapPlayers = $.getOverlaps().map(overlap => overlap.handle).filter(handle => handle != null && handle.type === "player");$.getOverlaps()でアイテムのOverlap Detector Shapeと重なっているオブジェクトの配列を取得することができます。
この配列からmap()でPlayerHandleの配列に置き換え、filter()でプレイヤーであるもの(playerHandleがnullでないもの)を抽出して、乗っているプレイヤーの配列を取得しています。
if (overlapPlayers.some(player => player.id == followingPlayer.id)) {配列のsome()メソッドで、追跡中のプレイヤーと同じプレイヤーが含まれるかどうかを判定しています。PlayerHandleはIDを比較することで、同じプレイヤーを指し示しているかどうかを判定することができます。
PlayerHandle自体の比較では、同じプレイヤーを指し示していても等価とならない場合があります。必ずIDを比較するようにしてください。
let followingPosition = followingPlayer.getPosition();PlayerHandle.getPosition()でプレイヤーの現在位置を取得できます。





















