【ベータ機能】近くのプレイヤーについてくるペットをつくる(プレイヤー情報取得)

本記事は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+方向に押し出す力を加えています。

記事をシェアしてワールド制作を盛り上げよう!

Cluster Creators Guide|バーチャル空間での創作を学ぶならをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む