本記事はCluster Creator Kitの「ベータ機能」を利用した解説になります。
ベータ機能では正式リリース前の機能を使うことができます。正式リリース前のため、不安定な挙動をしたり将来的に挙動が変わる可能性があります。
利用にはCluster Creator Kitでベータ機能を設定した状態でアップロードを行う必要があります。ワールドクラフトで利用する場合は、ワールドクラフトのワールドを新規作成する際にベータ機能の設定を行う必要があります。設定方法はこちらをご覧ください。
今回は「ワールド内にいるプレイヤーの位置などの情報を取得・操作できる」機能を使ったアイテムの作成方法を紹介します。
この機能を使って、近くのプレイヤーについてくるペットのようなアイテムをつくります。

サンプルコード
「Scriptable Item」「Movable Item」コンポーネントがついたアイテムを作成します。
Movable Itemと同時に追加されるRigidbodyコンポーネントでは「Use Gravity」を有効に、「Is Kinematic」を無効にしておいてください。
アイテムの子にコライダーやモデルを設定しますが、アイテムの原点が足元(接地部分)の位置に、正面がZ+方向になるようにしておきます。

Scriptable Itemコンポーネントに以下のスクリプトを設定します。
const force = 30;
const maxDistance = 10;
const minDistance = 1;
const rad2deg = (rad) => rad * 180 / Math.PI;
$.onUpdate(deltaTime => {
let position = $.getPosition()
let players = $.getPlayersNear(position, maxDistance);
let targetPlayer = null;
let targetDistance = Infinity;
// それぞれのプレイヤーとの距離を計算し、最も近いものを探す
players.forEach(player => {
let playerPosition = player.getPosition();
let distance = playerPosition.clone().sub(position).length();
if (distance < targetDistance) {
targetDistance = distance;
targetPlayer = player;
}
});
// 最も近いプレイヤーのPlayerHandleを保存し、$.onPhysicsUpdateで参照
$.state.targetPlayer = targetPlayer;
});
$.onPhysicsUpdate(deltaTime => {
let position = $.getPosition()
let player = $.state.targetPlayer;
if (player == null) return;
// 追跡中のプレイヤーがログアウトなどでいなくなっていた場合
if (player.exists() == false) return;
// プレイヤーがいる方向の角度を計算してY軸回転
let direction = player.getPosition().clone().sub(position);
let angle = rad2deg(Math.atan2(direction.x, direction.z)); // atan2は弧度法での角度を返すため、度数法に変換する
let rotation = new Quaternion().setFromEulerAngles(new Vector3(0, angle, 0));
$.setRotation(rotation);
// プレイヤーと一定より離れているときに、正面方向に押し出す力を加えて前進
if (direction.length() > minDistance) {
$.addForceAt(new Vector3(0, 0, force).applyQuaternion(rotation), position);
}
});
ベータ機能を有効にしたワールドまたはアイテムとしてアップロードし、確認してみましょう。
最も近くのプレイヤーを目指して、一定距離まで近づくように移動します。

サンプルコードの解説
新しい機能を利用している部分を中心に、サンプルコードを解説します。
let players = $.getPlayersNear(position, maxDistance);
$.getPlayersNear()
が新しく追加された機能です。ある点から一定距離までの範囲に存在するすべてのプレイヤーについて、対応するPlayerHandle
を配列として返します。PlayerHandle
を通してプレイヤーの情報を取得したり、操作することができます。
let playerPosition = player.getPosition();
このplayer
には$.getPlayersNear()
で取得した配列の要素であるPlayerHandle
が格納されています。PlayerHandle.getPosition()
メソッドでそのハンドルが指し示すプレイヤーのグローバル座標を取得できます。
forEach
文でPlayers
配列に含まれるすべてのプレイヤーについて座標を取得・計算し、アイテムから最も近いプレイヤーへの方向や距離を求めています。
$.onPhysicsUpdate(deltaTime => {
新しく追加された$.onPhysicsUpdate()
には物理演算の更新時に呼び出される処理を記述します。Unity C#におけるMonoBehaviour.FixedUpdate()
メソッドに相当するものです。
$.addForceAt(new Vector3(0, 0, force).applyQuaternion(rotation), position);
$.addForceAt()
メソッドは$.onPhysicsUpdate()のcallback
内でのみ呼び出すことができる、アイテムの指定した位置・方向に力を加える新しいメソッドです。
ここではアイテムの原点に対し、ローカルZ+方向に押し出す力を加えています。