本記事はCluster Creator Kitの「ベータ機能」を利用した解説になります。
ベータ機能では正式リリース前の機能を使うことができます。正式リリース前のため、不安定な挙動をしたり将来的に挙動が変わる可能性があります。
利用にはCluster Creator Kitでベータ機能を設定した状態でアップロードを行う必要があります。ワールドクラフトで利用する場合は、ワールドクラフトのワールドを新規作成する際にベータ機能の設定を行う必要があります。設定方法はこちらをご覧ください。
今回は「ワールド内にいるプレイヤーの位置などの情報を取得・操作できる」機能を使ったアイテムの作成方法を紹介します。
この機能を使って、「当アバターの移動についてくる床」をつくります。
サンプルコード
空の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.object.playerHandle).filter(player => player != null);
// ひとりも乗っていない場合は追跡しない
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.object.playerHandle).filter(player => player != null);
$.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()でプレイヤーの現在位置を取得できます。