見出し画像

ミミックボックスのしくみ

#clusterベータ機能ボタン展 ぼたんじま / BUTTON ISLANDに展示させて頂いたギミックのワールドクラフト(β)版です。


(※後日説明など追記予定)

召喚ボタン

召喚ボタンのオブジェクト構成
const id = new ItemTemplateId("【ミミックボックスのTemplateID】");
const position = $.getPosition().clone().add(new Vector3(0, 1, 1));
const rotation = new Quaternion().identity();
let mimicBox;
let isThere;

$.onInteract(() => {
    if(!isThere){
        $.log("ミミックボックスを召喚します...");
        mimicBox = $.createItem(id, position, rotation);
    }else{
        $.log("まだミミックボックスが存在しています");
    }
    isThere = mimicBox.exists();
});


ミミックボックス


ミミックボックスのオブジェクト構成
各部位の下層にはコライダーとメッシュがある
// 子オブジェクトを取得
const root = $.subNode("root");
const bones = {
    "hips": $.subNode("hips"),
    "spine": $.subNode("spine"),
    "chest": $.subNode("chest"),
    "neck": $.subNode("neck"),
    "head": $.subNode("head"),
    "leftUpperArm": $.subNode("leftUpperArm"),
    "leftLowerArm": $.subNode("leftLowerArm"),
    "leftHand": $.subNode("leftHand"),
    "rightUpperArm": $.subNode("rightUpperArm"),
    "rightLowerArm": $.subNode("rightLowerArm"),
    "rightHand": $.subNode("rightHand"),
    "leftUpperLeg": $.subNode("leftUpperLeg"),
    "leftLowerLeg": $.subNode("leftLowerLeg"),
    "leftFoot": $.subNode("leftFoot"),
    "rightUpperLeg": $.subNode("rightUpperLeg"),
    "rightLowerLeg": $.subNode("rightLowerLeg"),
    "rightFoot": $.subNode("rightFoot")
}

// 格納用リスト
let boneRot = [];
let ownerPos;
let owner;
const axises = [
    new Vector3(1, 0, 0),
    new Vector3(0, 0, 0)
];
const startPos = $.getPosition();
const startRot = $.getRotation();
const rad2deg = (rad) => rad * 180 / Math.PI;
let currentTime = 0;

// インタラクト時の処理
$.onInteract(player => {
    $.state.stand = !$.state.stand;
    if($.state.stand){
        $.state.owner = player;
        currentTime = 0;
        $.log("マネします。");
    }else{
        $.state.owner = null;
        $.setPosition(startPos);
        $.setRotation(startRot);
        $.log("マネをやめます。");
    }
    // $.log($.state.owner); 
});

// 大文字変換
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

// ボーンの回転をセットする関数
function boneSet(boneName){
    const playersBone = capitalizeFirstLetter(boneName);
    bones[boneName].setRotation($.state.owner.getHumanoidBoneRotation(HumanoidBone[playersBone]));
    bones[boneName].setPosition($.state.owner.getHumanoidBonePosition(HumanoidBone[playersBone]).sub($.state.owner.getPosition()));
};

// 初期化処理
function init(){
    $.setPosition(startPos);
    $.setRotation(startRot);

    $.state.stand = false;
    $.state.owner = null;
    $.state.initialized = true;
};

// 時間処理
$.onUpdate(deltaTime => {
    if(!$.state.initialized){
        init();
    }
    if($.state.stand && $.state.owner.exists()){
        for (const bone in bones){
            boneSet(bone);
        }
        $.setPosition(startPos);
        let direction = $.state.owner.getPosition().clone().sub(startPos);
        let angle = rad2deg(Math.atan2(direction.x, direction.z));
        $.setRotation(new Quaternion().setFromEulerAngles(new Vector3(0, $.state.owner.getRotation().y + Math.PI + angle, 0)));
    }
    if(!$.state.owner || !$.state.owner.exists()){
        if(currentTime > 30){
            currentTime = 0;
            $.log("ミミックボックスを送還します...");
            $.destroy();
        }else{
            currentTime += deltaTime;
        }
    }
});

(onStart()への変更、コード整理は未着手)


いいなと思ったら応援しよう!