なるべくカスタマイズしやすいエレベーターギミックを作ってみました。
オブジェクト構成
Main
└ Room(Scriptable Item)
├ Yuka(Cube)※エレベーターの床部
└ Panel(Cube)※エレベーター内のボタン設置
InsideSwitch(Parent Constraint -> Panel)※エレベーター内部のボタン
├ f1(Interact Item Trigger, SpecifiedItem f1 -> Main)
├ f2(Interact Item Trigger, SpecifiedItem f2 -> Main)
├ f3(Interact Item Trigger, SpecifiedItem f3 -> Main)
├ f4(Interact Item Trigger, SpecifiedItem f4 -> Main)
├ f5(Interact Item Trigger, SpecifiedItem f5 -> Main)
├ wrap(Set Game Object Gimmick, Key wrapon, Item Main)※ボタンロックコライダーf1
├ wrap(Set Game Object Gimmick, Key wrapon, Item Main)※ボタンロックコライダーf2
├ wrap(Set Game Object Gimmick, Key wrapon, Item Main)※ボタンロックコライダーf3
├ wrap(Set Game Object Gimmick, Key wrapon, Item Main)※ボタンロックコライダーf4
└ wrap(Set Game Object Gimmick, Key wrapon, Item Main)※ボタンロックコライダーf5
OutsideSwitch(Parent Constraint -> Panel)※エレベーター外部の呼び出しボタン
├ f1(Interact Item Trigger, SpecifiedItem f1 -> Main)
├ f2(Interact Item Trigger, SpecifiedItem f2 -> Main)
├ f3(Interact Item Trigger, SpecifiedItem f3 -> Main)
├ f4(Interact Item Trigger, SpecifiedItem f4 -> Main)
├ f5(Interact Item Trigger, SpecifiedItem f5 -> Main)
├ wrap(Set Game Object Gimmick, Key wrapon, Item Main)※ボタンロックコライダーf1
├ wrap(Set Game Object Gimmick, Key wrapon, Item Main)※ボタンロックコライダーf2
├ wrap(Set Game Object Gimmick, Key wrapon, Item Main)※ボタンロックコライダーf3
├ wrap(Set Game Object Gimmick, Key wrapon, Item Main)※ボタンロックコライダーf4
└ wrap(Set Game Object Gimmick, Key wrapon, Item Main)※ボタンロックコライダーf5
※階数を増やす場合は、ボタン部のオブジェクトを複製して増やしてください。
スクリプト
スクリプト部は冒頭のtarget配列に階数分の高さ情報を入れるだけで機能します。
const speed = 0.01; // 移動する速さ(大きいほど速くなります)
const target = [0.00, 7.00, 14.00, 21.00, 28.00]; // 移動先の高さリスト
const room = $.subNode("Room"); // エレベーターのカゴ
$.onUpdate(deltaTime => {
/* 初期設定 */
if (!$.state.initialized) {
$.state.initialized = true;
$.state.button = 100;
$.state.currenty = room.getPosition().y;
$.state.range = 0.00;
}
/* ボタン監視処理 */
// 階数を増やす場合、ボタンオブジェクトの key を、f1、f2、f3、f4、f5...の連番で追加ください。
for(let i = 1; i <= target.length; i++){
if($.getStateCompat("this", "f" + i, "boolean") && $.state.button >= 0) {
$.state.button = i - 1;
$.state.currenty = room.getPosition().y;
$.state.range = $.state.currenty - target[i-1];
$.setStateCompat("this", "f" + i, false);
}
}
/* 移動処理 */
if($.state.button != 100){
if($.state.range < 0.00){
let nowy = room.getPosition().y;
nowy = nowy.toFixed(2);
if(target[$.state.button] - nowy > 0.00){
$.state.currenty = $.state.currenty + speed;
let currenty = $.state.currenty;
currenty = currenty.toFixed(2);
let pos = new Vector3(0, currenty, 0);
room.setPosition(pos);
$.setStateCompat("this", "wrapon", true);
} else {
$.state.currenty = 0.00;
$.setStateCompat("this", "wrapon", false);
}
}
if($.state.range > 0.00){
let nowy = room.getPosition().y;
nowy = nowy.toFixed(2);
if(nowy - target[$.state.button] > 0.00){
$.state.currenty = $.state.currenty - speed;
let currenty = $.state.currenty;
currenty = currenty.toFixed(2);
let pos = new Vector3(0, currenty, 0);
room.setPosition(pos);
$.setStateCompat("this", "wrapon", true);
} else {
$.state.currenty = 0.00;
$.setStateCompat("this", "wrapon", false);
}
}
}
});