見出し画像

大きい乗り物アイテムで遊ぼう!

こんにちは。イナバです。
メタバースプラットフォーム clusterでアイテムやワールドを制作しています。

先日のアップデートにより、clusterのワールドクラフトアイテムにも乗り物機能が使用できるように。さらに、期間限定で様々なワールドにアイテムを持ち込むことができる「スペースクラフト」機能も実装されました。

本日はこの乗り物機能を利用して、大きい乗り物を作って遊んでいきたいと思います。


乗り物機能のCluster Script

乗り物機能のscriptはやまちゃんさんが公開していただいております!
詳しいコード解説も記載がありますので、ぜひご覧ください!

こちらのコードを少し改変して大きな乗り物を作りたいと思います。

クラフトアイテムのサイズ制限について

クラフトアイテムのサイズは基本的には4×4×4の中に納まる必要があり、それ以上大きいサイズのアイテムはアップロードができません(少しはみ出ても許される場合はある)

そこで、4×4×4のサイズの範囲にアイテムを収めてアップロードした後に、scriptの力で展開することで、これよりも大きいアイテムを持ち込むことができます。

詳しくはこちらの記事に記載しています

空飛ぶ絨毯を作ってみる

アイテムの構成

空のオブジェクト(オブジェクト名:空飛ぶ絨毯)に4×4の板のアイテム(A~D)を4つつけたアイテムを用意しました。

空のオブジェクトにはScriptble Item、Ridable Item、Movable Itemのコンポーネントをつけておきます。

空のオブジェクトに4つの板のアイテムつけています

Script全文

const seatA = $.subNode("A");
const seatB = $.subNode("B");
const seatC = $.subNode("C");
const seatD = $.subNode("D");

const VER_SPEED = 3; // [m/s]
const HOR_SPEED = 6; // [m/s]
const ANG_SPEED = 90; // [deg/s]
const hor_rot = new Quaternion().setFromAxisAngle(new Vector3(0, 1, 0), 180);

$.onStart(() => {
    $.state.driver = null;
    $.state.steerInput = new Vector2(0, 0);
    $.state.steerAdditionalAxisInput = 0;
});
$.onRide((isGetOn, player) => {
    $.state.driver = isGetOn ? player : null;

    const posA = Vector3(isGetOn ? -2 : 0, 0, 0);
    const posB = Vector3(isGetOn ? 2 : 0, 0, 0);
    const posC = Vector3(isGetOn ? -2 : 0, 0,isGetOn ? -4 : 0 );
    const posD = Vector3(isGetOn ? 2 : 0, 0,isGetOn ? -4 : 0 );

    seatA.setPosition(posA);
    seatB.setPosition(posB);
    seatC.setPosition(posC);
    seatD.setPosition(posD);
});
  
$.onSteer((input, player) =>{
    $.state.steerInput = input;
});

$.onSteerAdditionalAxis((input, player) => {
    $.state.steerAdditionalAxisInput = input;
});

$.onUpdate((deltaTime) => {
    if (!$.state.driver) {
        return;
    }
    if (!$.state.driver.exists()) {
        $.state.driver = null;
        return;
    }

    // note: original script causes error during changing avatar (null returned)
    //const direction = $.state.driver.getRotation().createEulerAngles();
    // player sit position is horizontally rotated 180 degs from ridable item
    const direction = $.getRotation().multiply(hor_rot).createEulerAngles();
    const forwardRadian = direction.y * Math.PI / 180;
    const sideRadian = ((direction.y + 90) % 360) * Math.PI / 180;

    const vectorForwardInput = new Vector3(
        Math.sin(forwardRadian) * $.state.steerInput.y * deltaTime * HOR_SPEED,
        0,
        Math.cos(forwardRadian) * $.state.steerInput.y * deltaTime * HOR_SPEED
    );
    const vectorSideInput = new Vector3(
        Math.sin(sideRadian) * $.state.steerInput.x * deltaTime * HOR_SPEED,
        0,
        Math.cos(sideRadian) * $.state.steerInput.x * deltaTime * HOR_SPEED
    );
    const vectorVerticalInput = new Vector3(
        0,
        $.state.steerAdditionalAxisInput * deltaTime * VER_SPEED,
        0
    );

    const newPosition = $.getPosition()
        .add(vectorForwardInput)
        //.add(vectorSideInput)
        .add(vectorVerticalInput);

    $.setPosition(newPosition);

    let rotation_side = new Quaternion().setFromAxisAngle(
        new Vector3(0, 1, 0), ANG_SPEED * $.state.steerInput.x * deltaTime);
    const newRotation = $.getRotation().multiply(rotation_side);

    $.setRotation(newRotation);
});

アイテムの挙動と解説

置いた状態では4×4のただの板ですが
座ると大きく展開して巨大な板になります

コードの以下のところで各オブジェクトの呼称を設定しています。
subNode("○○○")の中身はUnityで設定したオブジェクトの名前を入れてください。

const seatA = $.subNode("A");
const seatB = $.subNode("B");
const seatC = $.subNode("C");
const seatD = $.subNode("D");

const posA = Vector3(isGetOn ? -2 : 0, 0, 0);はアイテムに乗った際にAのアイテムの位置を指定しています。
Vector3(X, Y, Z)の中身はそのアイテムの位置を指定しています。この場合、乗った時にAのアイテムがX軸に-2、降りた時に0となるように移動します。
4つの板がうまく大きい板になるように、それぞれの移動位置を指定しています。

$.onRide((isGetOn, player) => {
    $.state.driver = isGetOn ? player : null;

    const posA = Vector3(isGetOn ? -2 : 0, 0, 0);
    const posB = Vector3(isGetOn ? 2 : 0, 0, 0);
    const posC = Vector3(isGetOn ? -2 : 0, 0,isGetOn ? -4 : 0 );
    const posD = Vector3(isGetOn ? 2 : 0, 0,isGetOn ? -4 : 0 );

    seatA.setPosition(posA);
    seatB.setPosition(posB);
    seatC.setPosition(posC);
    seatD.setPosition(posD);
});

使用例

例えば下のようなアイテムを作れば・・・

4×4×4におさまるように頭、足、腕のパーツをおさめています
座ると操縦できる巨大ロボに

ぜひ大きなアイテムを持ち込んで、
遊んでみてください!


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