GOGOバックダンサーズ
ちょこっと開閉するドアを作ってみたよ
付きなんて気の利いた事はしません。
だって、付けるだけscriptは複雑になるのに、ほとんどドアのは役に立たないんだもーん
とにかく興味があったら作ってみよう、れっつごー
ドアの動きは、llSetRotっていう関数を使って、水平にクルリと90度だけ回転させてあげるのが簡単かな?
そして最初に思いつくのが、touchイベントで開いて閉じる一連の動作をさせちゃう方法じゃないかなぁ
touchされたら 90度回転させて 数秒待って 元の角度に戻すの
ハイ出来上がり~
(Primは1つw llSetRotでは真ん中を中心に回転しちゃうので、パスカットで半分に切っちゃってます)
これでもちょこっと使うにはじゅうぶんだと思うけれど、案外llSetRotの角度とか難しいよね。
そのままだと、最初にrezした向きから90度開くだけで、編集で回転させても1度開くと元に戻っちゃってました。
ここはヒトツ工夫をして、ドアの長押しで新しい角度を記憶するようにしちゃおう
そうなると、touchイベントは使えません。これってtouchの判定だけで、押してるとか離したとか分からないのね。
だから今度はtouch_startイベント(タッチ開始)とtouch_endイベント(タッチ終了)の出番だよ
タッチ開始してから終了までが6秒以内ならドアを開いて、それ以上になったら今の角度をllGetRot()で取得しちゃえばいいわけ。
結構単純なのです、だって私が作ってるんだもの
だけどここで問題発生
ドアが開いてるときにタッチすると、何故だか閉じた後にまた開いちゃいます
6秒経ったかどうかも見えないから分からなくって使いにくいです
6秒で区切るには、llSetTimerEvent()で時間が来たらアクションを強制的に起こしちゃえばいいかな
連続で開いちゃう直接の原因は、なんとなくだけど「数秒待つ処理として使ってたllSleep()が原因のような気がしてきました。
llSleepでスクリプトが眠ってる間でも、こちらの操作が順番待ちに入っちゃう・・・ような感じなのかしら。よく分かりません
結局、ドアの「ぎー、バタン」を1つの所で処理してたのを「ぎー」と「バタン」に分けて、開いてる時間はllSetTimerEventを使う事にしました。
そしたら今度はタッチ連打で何回もドアが開いちゃって、なかなか閉じてくれません。うぅぅ
・・・えっと、こういう時は、、、状態表示を持たせて
・ドアが動いていない時はタッチの開始のみ
・ドアがタッチされてる時(今から開こうとしてる時)はタッチの終了のみ
・ドアが開いた時(今から閉じようとしてる時)はドアを閉じるのみ
の処理だけさせちゃえばいい・・・んだっけ?
うー、どんどん複雑になってくよー。あと1歩でこんがらがって分からなくなっちゃう
だけどなんとか間一髪のところで一応考えてた通りの動きにはなりました
音を付けて完成
うん、これでいいや、だって動くんだもんw
scriptここから
//通常はrezした時の角度で開閉を行いますが、ドアをタッチしたまま
//6秒間押したままにしておくことで、その時の角度を再取得します。
//ですので、rezした後に編集モードに入ってY軸の回転(青い輪方向の回転)
//を好みの方向に修正した後でドアを長押しすれば、そこから90度開く
//ようになります。
//Y軸をいじってから、長押しに失敗してドアを開いてしまうと、元の
//位置から90度開いた後、元の向きにドアが戻ってしまいます。注意!
rotation rot; //ドアが閉じた時の角度
integer door = 0; //ドアの状態表示 (0=停止, 1=開, 2=閉)
openDoor() ////////////////////ドアが開く時の処理だけをまとめています
{
//llPlaySound("doorOpen",1); //ぎぃぃ~音を再生します
llSetTimerEvent(5.0); //タイマーカウント開始!(ドアが開いてる時間)
door = 2; //ドアの状態を2(閉)にします
llSetRot(rot * llEuler2Rot(<0.0, 0.0, 90.0> * DEG_TO_RAD));
// 90度だけ回転させます
}
closeDoor() /////////////////ドアが閉じる時の処理だけをまとめています
{
//llPlaySound("doorClose",1); //バタン!音を再生します
door = 0; //ドアの状態を0に。これで閉じきるまで開こうとしないよ
llSetRot(rot); //最初の角度に戻します
}
default ////////////メインの処理です。この中をぐるぐる
{
state_entry() ///////////////////一番最初(rezした時?)に処理する部分
{
rot = llGetRot(); // 最初の角度を取得します
}
touch_start(integer total_number) //////////touch開始(ボタン押下)
{
if (door == 0) //ドアの状態が0(停止)の時だけ処理を始めます
{
llSetTimerEvent(6); //タイマーカウント開始!(長押しの時間)
door = 1; //ドアの状態を1(開)にして、開閉動作に入った事を記憶
}
}
touch_end(integer total_number) ///////////touch終わり(ボタン離す)
{
if (door == 1) //ドアの状態が1(開)の時だけドアを開く処理をします
{
openDoor(); //ドアを開ける処理を呼び出します
}
}
timer() //////タイマーが指定されたカウントになったら処理される部分
{
llSetTimerEvent(0); //タイマーのカウントを停止します
if (door == 1) //ドアの状態は1(開)ですか? 1ならdialogを出すよ
{
rot = llGetRot(); //6秒長押ししたときに rot を再取得するよ
door = 0; //ドアの状態を0に。これでdialogの時はドア開かない
llDialog(llGetOwner(),"Set This POSITION!",["agree"],-43);
}
else //ドアの状態が↑の1(開)じゃなければ、きっと2(閉)です
{
closeDoor(); //ドアを閉じる処理を呼び出します
}
}
}
scriptここまで
ちょこっと開閉するドアを作ってみたよ
付きなんて気の利いた事はしません。
だって、付けるだけscriptは複雑になるのに、ほとんどドアのは役に立たないんだもーん
とにかく興味があったら作ってみよう、れっつごー
ドアの動きは、llSetRotっていう関数を使って、水平にクルリと90度だけ回転させてあげるのが簡単かな?
そして最初に思いつくのが、touchイベントで開いて閉じる一連の動作をさせちゃう方法じゃないかなぁ
touchされたら 90度回転させて 数秒待って 元の角度に戻すの
ハイ出来上がり~
(Primは1つw llSetRotでは真ん中を中心に回転しちゃうので、パスカットで半分に切っちゃってます)
これでもちょこっと使うにはじゅうぶんだと思うけれど、案外llSetRotの角度とか難しいよね。
そのままだと、最初にrezした向きから90度開くだけで、編集で回転させても1度開くと元に戻っちゃってました。
ここはヒトツ工夫をして、ドアの長押しで新しい角度を記憶するようにしちゃおう
そうなると、touchイベントは使えません。これってtouchの判定だけで、押してるとか離したとか分からないのね。
だから今度はtouch_startイベント(タッチ開始)とtouch_endイベント(タッチ終了)の出番だよ
タッチ開始してから終了までが6秒以内ならドアを開いて、それ以上になったら今の角度をllGetRot()で取得しちゃえばいいわけ。
結構単純なのです、だって私が作ってるんだもの
だけどここで問題発生
ドアが開いてるときにタッチすると、何故だか閉じた後にまた開いちゃいます
6秒経ったかどうかも見えないから分からなくって使いにくいです
6秒で区切るには、llSetTimerEvent()で時間が来たらアクションを強制的に起こしちゃえばいいかな
連続で開いちゃう直接の原因は、なんとなくだけど「数秒待つ処理として使ってたllSleep()が原因のような気がしてきました。
llSleepでスクリプトが眠ってる間でも、こちらの操作が順番待ちに入っちゃう・・・ような感じなのかしら。よく分かりません
結局、ドアの「ぎー、バタン」を1つの所で処理してたのを「ぎー」と「バタン」に分けて、開いてる時間はllSetTimerEventを使う事にしました。
そしたら今度はタッチ連打で何回もドアが開いちゃって、なかなか閉じてくれません。うぅぅ
・・・えっと、こういう時は、、、状態表示を持たせて
・ドアが動いていない時はタッチの開始のみ
・ドアがタッチされてる時(今から開こうとしてる時)はタッチの終了のみ
・ドアが開いた時(今から閉じようとしてる時)はドアを閉じるのみ
の処理だけさせちゃえばいい・・・んだっけ?
うー、どんどん複雑になってくよー。あと1歩でこんがらがって分からなくなっちゃう
だけどなんとか間一髪のところで一応考えてた通りの動きにはなりました
音を付けて完成
うん、これでいいや、だって動くんだもんw
scriptここから
//通常はrezした時の角度で開閉を行いますが、ドアをタッチしたまま
//6秒間押したままにしておくことで、その時の角度を再取得します。
//ですので、rezした後に編集モードに入ってY軸の回転(青い輪方向の回転)
//を好みの方向に修正した後でドアを長押しすれば、そこから90度開く
//ようになります。
//Y軸をいじってから、長押しに失敗してドアを開いてしまうと、元の
//位置から90度開いた後、元の向きにドアが戻ってしまいます。注意!
rotation rot; //ドアが閉じた時の角度
integer door = 0; //ドアの状態表示 (0=停止, 1=開, 2=閉)
openDoor() ////////////////////ドアが開く時の処理だけをまとめています
{
//llPlaySound("doorOpen",1); //ぎぃぃ~音を再生します
llSetTimerEvent(5.0); //タイマーカウント開始!(ドアが開いてる時間)
door = 2; //ドアの状態を2(閉)にします
llSetRot(rot * llEuler2Rot(<0.0, 0.0, 90.0> * DEG_TO_RAD));
// 90度だけ回転させます
}
closeDoor() /////////////////ドアが閉じる時の処理だけをまとめています
{
//llPlaySound("doorClose",1); //バタン!音を再生します
door = 0; //ドアの状態を0に。これで閉じきるまで開こうとしないよ
llSetRot(rot); //最初の角度に戻します
}
default ////////////メインの処理です。この中をぐるぐる
{
state_entry() ///////////////////一番最初(rezした時?)に処理する部分
{
rot = llGetRot(); // 最初の角度を取得します
}
touch_start(integer total_number) //////////touch開始(ボタン押下)
{
if (door == 0) //ドアの状態が0(停止)の時だけ処理を始めます
{
llSetTimerEvent(6); //タイマーカウント開始!(長押しの時間)
door = 1; //ドアの状態を1(開)にして、開閉動作に入った事を記憶
}
}
touch_end(integer total_number) ///////////touch終わり(ボタン離す)
{
if (door == 1) //ドアの状態が1(開)の時だけドアを開く処理をします
{
openDoor(); //ドアを開ける処理を呼び出します
}
}
timer() //////タイマーが指定されたカウントになったら処理される部分
{
llSetTimerEvent(0); //タイマーのカウントを停止します
if (door == 1) //ドアの状態は1(開)ですか? 1ならdialogを出すよ
{
rot = llGetRot(); //6秒長押ししたときに rot を再取得するよ
door = 0; //ドアの状態を0に。これでdialogの時はドア開かない
llDialog(llGetOwner(),"Set This POSITION!",["agree"],-43);
}
else //ドアの状態が↑の1(開)じゃなければ、きっと2(閉)です
{
closeDoor(); //ドアを閉じる処理を呼び出します
}
}
}
scriptここまで