ソラマメブログ
< 2008年07>
S M T W T F S
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
アクセスカウンタ
オーナーへメッセージ
読者登録
メールアドレスを入力して登録する事で、このブログの新着エントリーをメールでお届けいたします。 解除は→こちら
現在の読者数 3人

2008年03月22日

オブジェクト探知機(リンデンスクリプト Tips)

 
 オブジェクト探知機です。オブジェクトの名前を指定して実行するとオブジェクトが存在する座標を
IM経由で知らせます。座標のリンクをクリックするとその場所へテレポートが可能です。探知範囲は、
半径96mです。大切なオブジェクトを失ってしまったあなたへ・・w
「スクリプト内容」
//
//    SHOP ZERO Tips24 ObjectDetector v1.0
//
//                   Created by Zero2000 Kid     2008/03/21
// 

integer input_ch = 33;
integer range=96;
integer handle;
string target;
string simname;


output_info (vector v , string name) {
    string pos=(string)v.x + "/" + (string)v.y + "/" + (string)v.z;
    llInstantMessage(llGetOwner(),name+"--> secondlife://"+simname+"/"+pos);
}

default {
    state_entry(){
        handle = llListen(input_ch,"",llGetOwner(),"");
    }

    on_rez(integer param){
        llResetScript();
    }
    
    listen(integer ch, string name, key id, string message) {
        target=message;
        simname=llGetRegionName();
        llInstantMessage(llGetOwner(),"Searching " + target + " ....");
        state active_target;
    }
    
}


state active_target {
    
    state_entry(){
        llInstantMessage(llGetOwner(),"< active_target >");
        llSensor(target, NULL_KEY, ACTIVE, range, PI);
    }
    
    sensor(integer total_number) {
        integer i;
        for (i = 0; i < total_number; i++) {
            output_info(llDetectedPos(i),llDetectedName(i));
        }
        state passive_target;
    }
    
    no_sensor() {
        llInstantMessage(llGetOwner(),"active_target --> Not found.");
        state passive_target;
    }

}

state passive_target {
    
    state_entry(){
        llInstantMessage(llGetOwner(),"< passive_target >");
        llSensor(target, NULL_KEY, PASSIVE, range, PI);
    }
    
    sensor(integer total_number) {
        integer i;
        for (i = 0; i < total_number; i++) {
            output_info(llDetectedPos(i),llDetectedName(i));
        }
        state scripted_target;
    }
    
    no_sensor() {
        llInstantMessage(llGetOwner(),"passive_target --> Not found.");
        state scripted_target;
    }

}

state scripted_target {
    
    state_entry(){
        llInstantMessage(llGetOwner(),"< scripted_target >");
        llSensor(target, NULL_KEY, SCRIPTED, range, PI);
    }
    
    sensor(integer total_number) {
        integer i;
        for (i = 0; i < total_number; i++) {
            output_info(llDetectedPos(i),llDetectedName(i));
        }
        llInstantMessage(llGetOwner(),"Searching complete.");
        state default;
    }
    
    no_sensor() {
        llInstantMessage(llGetOwner(),"scripted_target --> Not found.");
        llInstantMessage(llGetOwner(),"Searching complete.");
        state default;
    }
    
}

「使用方法」
1. オブジェクトを1つ作成します。(球でもボックスでも何でも構いません。)
2. オブジェクトにスクリプトをドラッグします。
3. 探知したいオブジェクト名が、"hot coffee" だとしたらチャット入力欄に
   /33 hot coffee
  と入力します。
4. オブジェクト探知が始まります。
5. オブジェクトが見つかるとチャット欄にオブジェクト名と座標が表示されます。
6. 座標をクリックするとそのオブジェクトの場所へのテレポ画面が起動します。
7. テレポを実行するとオブジェクトの場所へ移動します。
  (距離が近すぎるとテレポに失敗するので、その場合は少し離れてみましょう)

 * 探知範囲は、最大96mなので見つからない場合は、オブジェクトを装着して
  ポイントを変えながら探すと良いかもしれませんw


「スクリプトの説明」
 今回のスクリプトのポイントは、センサーコマンドとステートを利用している点でしょうか。
大まかな流れとしましては、リッスンコマンドで、オブジェクト名入力を監視し、名前が
入力されるとセンサーコマンドを実行し、3種類のタイプのオブジェクトをステートを切り替
えながら順番に探知します。
 最初にdefaultのstate_entry()の中の以下のコマンドが実行されます。

  handle = llListen(input_ch,"",llGetOwner(),"");

 これは、オーナーの発言を、チャットチャンネルの変数input_chで指定した番号で監視し
ます。input_chは、1行目で33と指定していますので、チャットチャンネルの33番で監視す
ることになります。llListenの詳しい内容はこちら、llListenを参照ください。
チャット入力を検知するとlistenイベントが発生します。
このイベントの中では、以下の4つのコマンドが実行されます。

  listen(integer ch, string name, key id, string message) {
        target=message; // チャット入力された文字列をグローバル変数targetに格納
        simname=llGetRegionName(); // 現在地のSIM名をグローバル変数simnameに格納
        llInstantMessage(llGetOwner(),"Searching " + target + " ...."); // メッセージ表示
        state active_target;  // active_targetステートへ移行
    }

 active_targetステートに移行するとまずstate_entryの中の以下のコマンドが実行されます。

  llInstantMessage(llGetOwner(),"< active_target >"); // メッセージ表示
  // オブジェクトタイプACTIVEで、半径range(m),オブジェクト名targetという名前で探査する
  // rangeは、グローバル変数で、2行目で指定した96という数字が格納されています。
  // targetは、グローバル変数で、チャット入力されたオブジェクト名称が格納されています。
  llSensor(target, NULL_KEY, ACTIVE, range, PI); 

  llSensorの詳しい内容はこちら、llSensorを参照ください。
 センサーでオブジェクトが検知されるとsensorイベントが発生します。

  sensor(integer total_number) {
        integer i;
        for (i = 0; i < total_number; i++) { // 検出されたオブジェクトの数だけループ
            output_info(llDetectedPos(i),llDetectedName(i)); // 関数output_infoの呼び出し
        }
        state passive_target; // ステートの移行
    }

  関数output_infoでは、以下のコマンドが実行されます。
  output_info (vector v , string name) {
    // オブジェクトの座標を< x,y,z >という表記からx/y/zという表記に変換
      string pos=(string)v.x + "/" + (string)v.y + "/" + (string)v.z;
    // IM経由でオブジェクトの座標を通知
      llInstantMessage(llGetOwner(),name+"--> secondlife://"+simname+"/"+pos);
  }

 オブジェクトが何も検出されない場合は、no_sensorイベントが発生し、Not foundという
メッセージを通知します。
 その後は、同様の処理をオブジェクトタイプのPASSIVE,SCRIPTEDの順で実行します。
オブジェクトのタイプに関する説明は、llSensorを参照ください。
全てのタイプの探査が終了するとステートをデフォルトに戻します。
 今回は、オブジェクトの探知でしたが、タイプにAGENTと指定するとアバターも探知する
ことも可能です。次回は、アバターを検知して、そのアバターの位置へ瞬時にテレポート
するスクリプトでも紹介しようと思います。お楽しみに~(^-^)/

リンデンスクリプト Tips Intexへ




この記事へのトラックバックURL

この記事へのコメント
レーダーに探知されないアイテムを探してます。
Posted by かよこ at 2008年03月22日 12:44
このオブジェクト探知機気に入りました。

オブジェクトに入れて、イベントの時、みんなにフリー配布してもいいですか?
Posted by ayumi Otsuka at 2008年03月24日 11:08
かよこさん

こんにちは^^
レーダーに検知されないアイテムですか・・・
どのようなご利用を想定していますか?


ayumiさん

こんにちは^^
どうぞご自由に配布くださいw
Posted by ZEROZERO at 2008年03月25日 21:28
嫌がらせ防止に、ターゲットにされないためです。
Posted by かよこ at 2008年03月30日 12:50