scriptでクラフトアイテムのサイズ制限を突破する方法
こんにちは。イナバです。
メタバースプラットフォーム clusterでアイテムやワールドを制作しています。
本日は、scriptの力でクラフトアイテムのサイズ制限を突破して、でかいロボのアイテムを作っていきます。
アイテムのサイズ制限について
クラフトアイテムのサイズは4×4×4の中に納まる必要があり、それ以上大きいサイズのアイテムはアップロードがができません(少しはみ出ても許される場合はある)
そこで、4×4×4のサイズの範囲にアイテムを収めてアップロードした後に、scriptの力で展開して大きいサイズのアイテムを作っていきたいと思います。
アイテムの設定方法
今回はロボットのアイテムなので、頭、腕、胴体、足のパーツをそれぞれ4×4×4のサイズに納まるように制作し、それぞれのパーツをScriptable Itemをつけた空のオブジェクトに子オブジェクトとして設定します。
それぞれのパーツも空のオブジェクト(座標 0,0,0)に子オブジェクトとして設定することで位置を調整しやすくなります。
腕のパーツを例にすると、
空のオブジェクト「armR」(座標0,0,0)に腕のパーツ「armR1」を子オブジェクトとして設定し、4×4×4のサイズに納まるように「armR1」のTransformを調整しました。
この状態でアイテムをアップロードできれば準備完了です!
基本的なアイテムの設定方法は以下の記事も参考としていただければと思います。
scriptの記述方法
scriptは以前の記事にも記載しました、折りたたみ階段のギミックと、公式記事のオブジェクトの表示・非表示のギミックを組み合わせて記述します。
今回は、インタラクト(クリックやタップ)する前は頭のパーツのみを表示して、その他のパーツは非表示に。インタラクトするとすべてのパーツが表示されて揃うように設定していきたいと思います。
const stepA = $.subNode("head");
const stepB = $.subNode("body");
const stepC = $.subNode("leg");
const stepD = $.subNode("armR");
const stepE = $.subNode("armL");
//subNodeの中身はUnityで設定したオブジェクトの名前を入れる
$.onInteract(() => {
let isOpen = $.state.isOpen;
isOpen = !isOpen;
$.state.isOpen = isOpen;
//インタラクトするとisOpenの状態になる。
if(isOpen == null) isOpen = stepB.getEnabled();
if(isOpen == null) isOpen = stepC.getEnabled();
if(isOpen == null) isOpen = stepD.getEnabled();
if(isOpen == null) isOpen = stepE.getEnabled();
// 初期化されていなければ、現在のアクティブ状態で初期化
const posA = Vector3(0, isOpen ? 8: 0, 0,);
const posB = Vector3(0, isOpen ? 4: 0, 0,);
const posC = Vector3(0, 0, 0,);
const posD = Vector3(isOpen ? 3.2: 0, isOpen ? 4.5: 0, 0,);
const posE = Vector3(isOpen ? -3.2: 0, isOpen ? 4.5: 0, 0,);
//isOpenがtureとなったときの各オブジェクトの位置を変更する。
//Vector3(X,Y,Z)がそれぞれアイテムのX,Y,Z座標を指定している
//isOpen ? A:BはisOpenがtureならA、falseならBの位置になります
stepA.setPosition(posA);
stepB.setPosition(posB);
stepC.setPosition(posC);
stepD.setPosition(posD);
stepE.setPosition(posE);
//各subNodeの位置(pos)を指定する。
stepB.setEnabled(isOpen);
stepC.setEnabled(isOpen);
stepD.setEnabled(isOpen);
stepE.setEnabled(isOpen);
// アクティブ状態を設定(isOpenがtrueなら表示、falseなら非表示になる)
});
script冒頭のsubnodeの中には動かしたいオブジェクト名を記載するのですが、この時記載するのは各パーツを子オブジェクトとしてつけた空のオブジェクトの名称を記載します
Vector3(X,Y,Z)の中身の数字を変えることによって、アイテムの移動場所を調整することができます。
冒頭のタッチして変形するロボットの変形の動きはこのscriptで記述しています。
なお、Ridable ItemとsitPositionを設定し、$,onInteractを$.onRideに書き換えると、座ると変形するアイテムを作ることもできます。
スクリプトアイテムの仕様上、最初にアイテムを置いたときはすべてのアイテムが表示された状態となってしまいますが、一度プレイモードでインタラクトすると、その後は正しく表示されるようになります!
クラフトアイテムとして公開してます。お試しあれ!
応用編
このスクリプトを使えば、ワールドのどこにでもアイテムを瞬間移動させることが可能です。
例えば下のような鍵と板のアイテムで瞬間移動のギミックを作ってみましょう。
const stepA = $.subNode("Key");
const stepB = $.subNode("bridge");
//subNodeの中身はUnityで設定したオブジェクトの名前を入れる
$.onInteract(() => {
let isOpen = $.state.isOpen;
isOpen = !isOpen;
$.state.isOpen = isOpen;
//インタラクトするとisOpenの状態になる。
if(isOpen == null) isOpen = stepA.getEnabled();
if(isOpen == null) isOpen = stepB.getEnabled();
// 初期化されていなければ、現在のアクティブ状態で初期化
const posB = Vector3(0, 0, isOpen ? -7: 0,);
//isOpenがtureとなったときの各オブジェクトの位置を変更する。
//Vector3(X,Y,Z)がそれぞれアイテムのX,Y,Z座標を指定している
//isOpen ? A:BはisOpenがtureならA、falseならBの位置になります
stepB.setPosition(posB);
//各subNodeの位置(pos)を指定する。
stepA.setEnabled(!isOpen);
stepB.setEnabled(isOpen);
// アクティブ状態を設定(isOpenがtrueならstepAを表示、falseならBを表示になる)
});
今回はインタラクトする前は鍵のみを表示、インタラクトすると板のみを表示、板の位置をZ軸方向後方に7M移動させる内容です。
頑張ればもっと複雑で遠くの位置への瞬間移動も可能です。
ワールドクラフトでも、鍵を集めることでゴールまでの道が出現するようなゲームワールドを作ることができるかも!
ぜひお試しください!
※最後に紹介したscriptを使用して、特定のアイテムをとる事で先に進める足場が出現するワールドを制作しました。