Posts
SIMにやさしい版をつくりました。
http://slurl.com/secondlife/Armon%20Gill/185/117/40/ に動くものをおいてあります。
float ibias = 2; //移動距離
vector vbias = <0,0,0>;
string sobject_status = "close";
float ftiming = 5;
move_object()
{
vector foo = llGetLocalPos();
vbias.y = ibias;
ibias = -ibias;
llSetPos(foo + vbias);
}
default {
collision_end(integer num_detected) {
if (llDetectedType(0) & AGENT)
{
if (sobject_status == "close")
{
move_object();
sobject_status = "open";
llSetTimerEvent(ftiming);
}
}
}
timer()
{
if ( sobject_status == "open")
{
llOwnerSay(sobject_status);
llOwnerSay("timer");
move_object();
sobject_status = "close";
llOwnerSay(sobject_status);
llSetTimerEvent(0);
}
}
}
自動ドアをLSLで作るには、まず自動ドアの仕様(?)を決めなければなりません。
今回はこんな仕様でいきます。
1.自動ドアオブジェクトの前に誰かが立つと
2.自動ドアオブジェクトが移動して
3.一定時間が経つと元に戻る
*作り方
まずオブジェクトが、人がいることを判断しないといけません。それにはllsensorを使います。
llsensorとはある範囲内に何かがあることをチェックするためのものです。流れとしては下記のとおり。
1.オブジェクトが起動したときに呼ばれるdefaultでチェックルーチンを呼ぶ。
2.llsensorでチェックする対象や範囲を指定しておく。
3.その範囲に対象が入ってくるとsensorハンドラが呼ばれるので、そこに処理を書く。
=5m以内にアバターがいると、その名前を表示して終了するサンプルプログラム
default
{
state_entry(){
llSay(DEBUG_CHANNEL,"check start!");
llSensor("","",AGENT,5.0,PI); // どんな名前のアバターでもいいので半径5mの球に入った場合。
}
// Sensor handler
sensor(integer total_number)
{
llSay(DEBUG_CHANNEL, (string)total_number + " avatars in 5m around" );
}
}
llSensorの詳しい説明はこちら。
http://rpgstats.com/wiki/index.php?title=LlSensor
これをオブジェクトに張っておくと、誰かがそのオブジェクトの5m以内に近づくと、5m以内にいる人数を表示します。
TIP!!
llSay(DEBUG_CHANNEL,"check start!");
のように書いておくとデバックチャンネルだけで表示されるのでテストに便利です。
-----------------------------------------------------------
次はオブジェクトを移動してみます。テストのため触るとX軸の方向に3m右移動し、もう一度触ると元に戻るようにしてみます。
移動するにはllSetPosを、今の位置を得るにはllGetLocalPos()を使います。
流れは以下になります。
1.オブジェクトを触ると
2.今の位置を保存します
3.どちらに移動するかをチェックし
3.3m移動させます。
=触ると3m移動し、もう一度触ると元の位置に戻るサンプルプログラム
float ibias = 3;
vector vbias = <0,0,0>;
default
{
touch(integer total_number)
{ //触ったら
vector foo = llGetLocalPos(); //今の場所
vbias.x = ibias; // 移動方向
ibias = -ibias; //元に戻すための処理
llSetPos(foo + vbias); //移動
}
}
llSetPosの詳しい説明はこちら。
http://wiki.secondlife.com/wiki/LlSetPos
-----------------------------------------------------------
最後に3秒経過すると何かのアクションをするスクリプトです。これにはllSetTimerEventを使います。
llSetTimerEvent(秒数)と指定しておくと、その秒数毎にtimer()という関数が呼ばれます。
=一度触ると5秒おきに"5 seconds counted."と表示し、もう一度触ると止まるサンプルプログラム
float ftiming = 5;
default
{
touch(integer total_number)
{
llSetTimerEvent(timing);
if ( ftiming > 0 )
{
ftiming = 0;
} else {
ftiming = 5;
}
}
timer()
{
llOwnerSay("5 seconds counted.");
}
}
llSetTimerEventの詳しい説明はこちら。
http://rpgstats.com/wiki/index.php?title=LlSetTimerEvent
-----------------------------------------------------------
さて、これら3つを組み合わせれば自動ドアができます。誰かをはさまないようにもなっています。
float ibias = 3; //移動距離
vector vbias = <0,0,0>;
float ftiming = 3; // 閉じるまでの時間
string sobject_status = "close";
default
{
state_entry(){
llSetTimerEvent(0); //閉じるタイマーを止めておく。
// どんな名前のアバターでもいいので半径5mの球に入った場合
llSensorRepeat("","",AGENT,5.0,PI,1);
}
// Sensor handler
sensor(integer total_number)
{
if ( sobject_status == "close")
{
llSensorRepeat("","",AGENT,5.0,PI,0);
vector foo = llGetLocalPos();
vbias.x = ibias;
ibias = -ibias;
llSetPos(foo + vbias);
sobject_status = "open";
llSetTimerEvent(ftiming);
}
}
no_sensor()
{
if ( sobject_status == "open")
{
llSetTimerEvent(0);
vector foo = llGetLocalPos();
vbias.x = ibias;
ibias = -ibias;
llSetPos(foo + vbias);
sobject_status = "close";
llSensorRepeat("","",AGENT,5.0,PI,1);
}
}
timer()
{
// ftimingおきにセンサーを起動し、誰かいないかをチェックする
llSensor("","",AGENT,5.0,PI); //センサー起動
}
}