空飛ぶ絨毯(じゅうたん)の作成

スクリプトの基本的な作り方が分かったところで、何か面白いスクリプトの例として「空飛ぶ絨毯(じゅうたん)」を作ってみようと思います。これは、アバターが絨毯の上に座ると、アバターを乗せて空を飛ぶというものです。

実際に何か作ってみる前に、どうしたら、思い通りの動きができるのか考えてみます。ここで作る絨毯は以下のようなものです。

  1. アバターが絨毯に座ったら絨毯を空中に浮かせる
  2. タイマーを設定して自動的に少しずつ絨毯を動かす
  3. 絨毯を触ると、進行方向を90度変更する
  4. アバターが絨毯から降りたら絨毯を地上に降ろす

絨毯のプリム作る

まず、絨毯のプリムを作ってみます。ここでは、絨毯を、薄い板として作ります。Sandboxに移動して、パイメニューの「作成」を選ぶか、画面下の[建造]ボタンをクリックします。以下の図のようなダイアログが出ますので、立方体を選択して、地面にプリムを作成します。

立方体のプリムを選択します。

プリムを作成したら、[Ctrl]+[Shift]キーを押してポイントをドラッグして、プリムが絨毯に見えるように薄く伸ばします。

立方体を薄くして伸ばします。

このままでも絨毯に見えないこともないのですが、より本物っぽくするためには、テクスチャを利用します。編集にして、[全表示ボタン]をクリックして全ての編集メニューを見えるようにします。そして、テクスチャの四角の枠をクリックすると、テクスチャの選択画面になります。テクスチャ(texture)とは、英語で、生地とか外見、表面の感じを表す単語です。

テクスチャを選択します。

スクリプトを作成する

続いて、スクリプトを記述していきます。コンテンツタブから[新しいスクリプト]をクリックすると、New Scriptというファイルが出来ます。これをダブルクリックすると、スクリプトエディタが開きます。

以下が空飛ぶ絨毯のスクリプトです。コピーして、スクリプトエディタに貼り付けると良いでしょう(日本語のコメントは文字化けしてしますが、実行はできます)。

スクリプトを保存して、プリムの作成・編集ダイアログを閉じると動き出します。

//----------------------------------------------------------
// 空飛ぶ絨毯のスクリプト
//----------------------------------------------------------
// グローバル変数
integer dir = 0;
list dir_list = [<1,0,0>,<0,1,0>,<-1,0,0>,<0,-1,0>];

default
{
    // プログラムの初めに実行される処理
    state_entry()
    {
        // アバターが座る位置を指定する
        llSay(0, "It flies when sitting here. ");
        llSitTarget(<2.4, 0, 0.3>, ZERO_ROTATION);
    }

    // アバターが触った時に実行される処理
    touch_start(integer total_number)
    {
        // 触ると向きを90度回転する
        dir = (dir + 1) % 4;
        llSetRot( llEuler2Rot(<0,0,90*DEG_TO_RAD*dir>) );
        llSay(0,"Turn " + (string)(dir * 90));
    }

    // 一定間隔ごとに実行される処理
    timer()
    {
        // 向いている方向へ進む
        llSetPos( llGetPos() + llList2Vector(dir_list, dir));
   }

    // 状態が変化したときに実行される処理
    changed( integer change )
    {
        if (change & CHANGED_LINK) {
            // 座るのか立つのか判別する
            key av = llAvatarOnSitTarget();
            if (av == NULL_KEY) {
                // 立ち上がったときに実行される
                llSetTimerEvent(0);
                llSay(0,"Stop");
                llSetPos( llGetPos() + <0,0,-2.0>);
                llUnSit(av);
            } else {
                // 座ったときに実行される
                llSay(0,"Start!");
                llSay(0,"It turns when touching the carpet. ");
                llSetPos( llGetPos() + <0,0,2>);
                llSetTimerEvent(1);
            }
        }
    }
}

おとぎ話にあるような空飛ぶ絨毯には見えないかもしれませんが、悠々と空を飛びます。

スクリプトの解説

いきなり、空飛ぶ絨毯の完成形をお見せしました。それほど長くないとはいえ、このプログラムの内容を一気に理解するのは無理でしょう。そこで、1つずつの要素に分けてスクリプトの機能を紹介したいと思います。

プリムの移動

はじめに、絨毯のプリムに触ったとき、絨毯を1m上昇させるというスクリプトを作ってみます。

プリムを移動させるためには、「llSetPos()」命令を使います。「llSetPos()」は以下の書式で使います。

 llSetPos( 座標 )

座標の指定は、 のように指定します。Second Lifeは、3次元空間なので、X軸とY軸に加えて、高低を表すZ軸が存在するのです。例えば、<85, 220, 65>の座標に移動するには、次のように記述します。

 llSetPos( <85, 220, 65> );

この命令だけを使えば、絨毯の移動ができそうに思いますが、絨毯を動かすのにあたって、このような絶対座標を指定してしまっては、絨毯を別の場所に設置するのが難しくなってしまいます。(実行するたびに同じ位置に戻ってしまいます。)

そこで、現在の座標を得ておいて、そこから相対的にいくらか移動することにすれば、絨毯を持ち運んでどこでも使うことができます。

プリムの現在の座標を得るには、「llGetPos()」命令を使います。例えば、プリムを空中に1m浮かせるには次のように書きます。

 llSetPos( llGetPos() + <0, 0, 1> );

これで、プリムの移動方法が分かりましたので、アバターが絨毯を触ったときに1m上昇させるというプログラムを作ってみます。

絨毯に触ると(クリックすると)絨毯が1m浮き上がります

触ると(touchすると)絨毯が上昇するプログラム:

default
{
    // プリムを触ったときに実行される処理
    touch_start(integer total_number)
    {
        llSay(0, "Touched.");
        llSetPos( llGetPos() + <0,0,1> );
    }
}

定期的に処理を実行する

絨毯が空中に浮上してから、定期的に絨毯を前進させる必要があります。何かしら定期的に処理を実行するためには、タイマー機能を利用します。

タイマーを利用するには「llSetTimerEvent(秒数)」命令を利用します。タイマーの発生間隔を指定すると、指定した秒数ごとに、timerイベントに記述した処理を実行します。

例えば以下のように書くと、2秒ごとにチャットウィンドウに「timer」と表示します。

タイマーの使い方サンプル:

default
{
    state_entry()
    {
        llSetTimerEvent(2);
     }
    timer()
     {
        llSay(0, "timer");
    }

タイマーを使うためには、上記のように、「llSetTimerEvent(秒数)」命令を設定し、「timer() { .. }」の中に実行したい処理を記述します。もし、タイマーを解除したい場合は、「llSetTimerEvent(0)」と記述します。

タイマーは、他のいろいろな処理を行う上で有用な機能です。今回は、空飛ぶ絨毯を定期的に前進させるために使いますが、自動ドアを作る時に、人が通り過ぎた後、数秒後にドアを閉める処理を行うような場合にも使えますし、数秒ごとに色の変わる造形物を作る時にも使えるでしょう。

アバターが絨毯に座ったとき、立ち上がったとき

タイマーでも見ましたが、Second Lifeでは、タイマーイベントが発生したとき、プリムを触ったときなど、様々なイベントが発生しますので、このイベントに応じた処理を記述していくことになります。こうしたイベントに応じてプログラムを組み立て、実行する方式を、イベントドリブン方式と言います。

アバターがプリムに座ったとき、立ち上がったときには、changedイベントが発生しますので、アバターが絨毯に座ったら絨毯を空中に浮かせ、立ち上がった時に、地面に下ろすという処理を行うのには、このchangedイベントを利用しています。

以下は、アバターがプリムに座った時に「Sat」、立ち上がった時に「Stood」と表示するプログラムです。

アバターが座ったとき、立ち上がったときの状態を表示するサンプル:

default
{
    state_entry()
    {
        // アバターの座り位置を指定する
        llSitTarget(<0, 0, 0.3>, ZERO_ROTATION);
    }
    changed( integer change )
    {
        // アバターが座った時、立った時
        if (change & CHANGED_LINK) {
            key av = llAvatarOnSitTarget();
            if (av == NULL_KEY) {
                llSay(0,"Stood"); // 立ち上がった時の処理
            } else {
                llSay(0,"Sat"); // 座った時の処理
            }
        }
    }
}