見出し画像

ClusterScriptでオーナー取得(※CCK専用)

この記事ではタイトルのまんまClusterScriptで(だいたい)オーナー取得する方法について書きます。

実際の挙動

最初にエントリー用のボタンを押す必要があります。

ネタバラシ(有識者向け🌶️🌶️🌶️)

①適当なアイテムのInteractなどでplayer.idの12桁をsetStateCompatでプレイヤーに保存
②オーナー取得アイテム側ですべてのプレイヤーを取得
③アイテムオーナーの12桁のidからプレイヤーを検索
④一致したらそのplayerがアイテムオーナー
⑤アイテムオーナーが変更されると12桁idが一致しなくなる

詳細については、多分スクリプト見て理解できるでしょう。

エントリーボタンスクリプト

$.onInteract(player =>
{
    var playerIdLast = getIdLast(player.id);
    $.setStateCompat("owner", "playerIdLast", playerIdLast);});

/**
 * Idの下12桁を取得する
 * @param {ID} id 
 * @returns idの下12桁
 */
function getIdLast(id)
{
    return parseInt(id.slice(-12),16);
}

オーナー取得側スクリプト

const ownerLabelNode = $.subNode("OwnerLabel");

//オーナー遷移テスト用
$.onInteract(() => { });

$.onUpdate(dt => {

    //ラベルの表示を更新
    ownerLabelNode.setText(`OWNER: ${$.state.owner ? $.state.owner.userDisplayName : "NOT_ENTRY"}`);

    //オーナーがいない場合
    if ($.state.owner == null) {
        $.state.owner = findOwner();
        return;
    }

    //オーナーが変更されたとき
    if (getOwnerChanged()) {
        $.state.owner = null;
        $.log("Owner changed");
        return;
    }

    //--- 以下、オーナーがいる場合の処理 ---

    //Y軸を固定して、オーナーの位置に向かって回転する
    const currentPos = $.getPosition();
    const targetPos = $.state.owner.getPosition();
    const targetDir = targetPos.sub(currentPos).normalize();
    const angle = Math.atan2(targetDir.x, targetDir.z) * 180 / Math.PI;
    const rotation = new Quaternion().setFromAxisAngle(new Vector3(0, 1, 0), angle);
    $.setRotation(rotation);
});

/**
 * オーナーを探す
 * @returns オーナー、見つからない場合はnull
 */
function findOwner() {
    const players = $.getPlayersNear(new Vector3(0, 0, 0), Infinity);
    const ownerIdLast = $.getStateCompat("owner", "playerIdLast", "double");

    for (let player of players) {
        if (getIdLast(player.id) == ownerIdLast) {
            return player;
        }
    }
    return null;
}

/**
 * オーナーが変更されたかどうか
 * @returns オーナーが変更された場合true
 */
function getOwnerChanged() {
    if ($.state.owner == null)
        return false;

    if (getIdLast($.state.owner.id) != $.getStateCompat("owner", "playerIdLast", "double"))
        return true;

    return false;
}

/**
 * Idの下12桁を取得する
 * @param {ID} id
 * @returns idの下12桁
 */
function getIdLast(id) {
    return parseInt(id.slice(-12), 16);
}

注意事項

0.000000000000035%くらいの確率でおかしくなります。
(16^12通りが被る確率)
(年末ジャンボ宝くじが大体14073748回当たる確率)

この記事が気に入ったらサポートをしてみませんか?