SecondLife Furry's Habitat Wiki - サーガルでもわかる!スクリプトのススメ(第一回)
サーガルでもわかる!スクリプトのススメ
第1回:とりあえず動かしてみよう!

やぁみんな、しぃがるだよ。しぃがる日本橋店って最高だね!みんなもそうおもうだろ?

今回はセカンドライフ内で何か物を作るのにもはや基本知識になりつつある「スクリプト」の初心者入門講座を書いてみたよ。
「スクリプト…プログラム…うっ頭が」ってなるボーイもガールも怖がらずに挑戦してほしいな!

はじめに

ここはlsl(Linden Scripts Language)の超絶初心者向け講座です。
プログラム?んなもんやったことねぇよ!って人でも理解できるように書いたつもりです…がどうしてもわかりづらいとこがあると思います。
そういう時は習うより慣れろ精神でとりあえず動かしてみると案外すんなりできちゃったりします。トライアンドエラーでやってみてください。こっちもできる限り頑張って書きます。

逆に、ある程度lslを触ったことのある人にとっては「基本すぎてアクビがでちまうぜェ〜」な内容だと思います。
そういう方は是非是非登り続けてください…この果てしなきスクリプト道をよ…!

スクリプトでできること!

スクリプトにできることを簡潔に書くならば、セカンドライフ内の物品(オブジェクト)に「機能を与える」ことです。
オブジェクトに「動作アニメーションや音、弾を撃つ機能を付加」したり、「ワープする機能」といったものを付加する…それがスクリプト!

オブジェクトの作り方

スクリプトの書き方の前にまずオブジェクトの作り方について最低限だけ説明します。
さっきも書いたとおり、スクリプトはオブジェクトありきのものなんだ。オブジェクトがないと、そもそも機能を与える対象がないわけだし!

というわけでまずは新しくオブジェクトを生成してみましょう。
キーボードのB(Mac使いはcommand+B)を押して製作メニューを表示させましょう。
そのままインワールドの適当なところをクリックすると木目の箱が出現すると重います。
今回はこれをいじっていきましょう。

※その土地でのRez権限がないと生成できません。

スクリプトの作り方

さて、オブジェクトを作成できたところで、スクリプトを実際に書いてみましょう。
オブジェクトを右クリック>編集>「中身」タブを選択し、「新しいスクリプト」ボタンをクリックしましょう。

ちょっとすると、新しいスクリプトがオブジェクト内に生成されます。

スクリプトの中身をみてみよう!

生成した「新しいスクリプト」を右クリック>編集で編集してみましょう。
以下の様な内容が既に入っていると思います。
default
{
    state_entry()
    {
        llSay(0, "Hello, Avatar!");
    }
 
    touch_start(integer total_number)
    {
        llSay(0, "Touched.");
    }
}

スクリプトは3つの階層でできている!

LSLは大きく分けて「ステート」「イベント」「関数」の3つで構成されています。

この図でいうところの赤がステート、緑がイベント、青が関数を示しています。

関数

関数は簡単にいえば「○○をする」を示しています。
イベントの内部にのみ配置することが可能です。

デフォルトのスクリプトでは
llSay(0, "Hello, Avatar!");
llSay(0, "Touched.");
が関数となります。

関数は以下のルールに則って記述されます。
関数名(値);

関数名は、単純に言えば「○○する」の"動作"を表しています。
サンプルのllSayという関数は、「チャットで発言する」という"動作"になります。

値は、その関数を実行するのに必要な変数を入力する場所です。
llSayで指定しなくてはならない変数は、一番目に「発言するチャンネル」、二番目に「発言する内容」の2つです。

これを踏まえてサンプル関数を無理やり日本語っぽくしてみましょう。
default
{
    state_entry()
    {
        発言します(0チャンネルで, "Hello, Avatar!"と);
    }
 
    touch_start(integer total_number)
    {
        発言します(0チャンネルで, "Touched."と);
    }
}

関数名の部分を書き換えれば動作が、値を書き換えればその内容が変化します。
試しにllSayの2番目(""で囲まれた文章のぶぶん)を以下のように書き換えてみましょう。
default
{
    state_entry()
    {
        llSay(0, "はろーわーるど!!");
    }
~~(省略)
}
書き換えた上で保存をすると、オブジェクトが「はろーわーるど!!」と発言するはずです。
うまく行かなかった場合は、ちゃんと""の中に文字がはいっているか、カッコが外れていないか等をチェックしてみましょう。

次に関数名を他のものに変更してみましょう。
今回はllSayの亜種であるllShoutを用います。
llShoutで指定しなくてはならない変数は、一番目に「発言するチャンネル」、二番目に「発言する内容」の2つです。

では以下のように「llSay」を「llShout」に書き換えてみましょう。
default
{
    state_entry()
    {
        llShout(0, "Hello, Avatar!");
    }

~~(省略)
}
この状態で保存すると、オブジェクトはHello, Avater!と「叫ぶ」ようになります。
llShout関数は「チャットで叫ぶ」関数なので、llSayと異なりより広範囲のアバターにも表示される発言となります。

ちなみにllWhisper関数を用いれば「チャットでささやく」になり、逆に近い距離にしか届かない発言にすることができます。
小話~llSay();の詳しい解説
llSay関数の値についてより詳しく説明します。(あれ…)と思い始めた時に読むとよいでしょう。
LSLポータルのllSayの項目をみると、このように書いてあります。

llSay(integer channnel,string msg);
これは

一番目の値がinteger属性(整数値)で、channnelを指定
二番目の値がstring属性(文字列)で、表示するmessageを入力せよ
という意味です。

channelとはラジオの周波数のようなもので、Listenイベントを用いる際に非常に重要なものとなります。
Listenイベントに関する詳しい説明は省きますが、「いつものチャットはチャンネルが0」という事は覚えておいてください。0以外を指定した場合、チャット画面には表示されません。
先ほど紹介したllShoutやllWhisperは届く距離が違うだけで、「周囲に対して、指定したチャンネルに文字列を発信する」という点で原則的には同じものです。

ここでllOwnerSay関数を見てみましょう。
llOwnerSay(string msg);
このように「Ownerにしか聞こえない」といったふうにチャンネルもクソもない関数であれば、1番目のchannel指定がいらないというわけです。逆にいれるとエラー吐かれます。

このように、LSLポータルの関数ページを読むことで、それぞれの関数の機能と必要となる値を理解することができます。
スクリプトをはじめるうえで、LSLポータルは必須になるので、今のうちに慣れておきましょう。

イベント

イベントとは即ち「発動条件」です。
イベントの条件を満たした時、そのイベントの中にある関数を動作させる形になります。


色で言うところの緑がイベントの部分です。

デフォルトのスクリプトでは
state_entry() : このステートが開始したとき。
touch_start(integer total_num) : このオブジェクトがタッチされはじめたとき。
の2つが使われています。

これを踏まえてサンプルのイベントを無理やり日本語っぽくしてみましょう。
default
{
    defaultステートが開始したとき、カッコ内の関数を発動させます。
    {
        発言します(0チャンネルで, "Hello, Avatar!"と);
    }
 
    オブジェクトがタッチされはじめたとき、カッコ内の関数を発動させます。
    {
        発言します(0チャンネルで, "Touched."と);
    }
}

整理すると、このスクリプトは以下の2つの機能があると考えることができます。
・「state_entryという条件を満たした時、llSay(0, "Hello, Avatar!");を作動させる」
・「touch_startという条件を満たした時、(llSay(0, "Touched.");を作動させる」

touch_start(integer total_number)イベントは「オブジェクトをタッチし始めた時」という条件となります。
よって箱をクリックすると(llSay(0, "Touched.");が発動し、「Touched.」と発言されます。

イベントの後に存在する{ } はイベントの範囲を示しています。
イベントの中には、好きなだけ関数を入れることができる…と考えて頂いて結構です。(正確には違いますが…)
イベント内の関数は基本的に「上から順番に処理されます」。

以下のように書き換えてみましょう。
default
{
    state_entry()
    {
        llSay(0, "Hello,Avatar!");
    }
 
    touch_start(integer total_number)
    {
        llSay(0, "Touched.");
        llSay(0, "触られました");
    }
}
touch_startの{}内に一つllSayを増やしてみました。
これを保存した状態で箱をクリックすると、「Touched.」と「触られました」と順番に箱がしゃべるはずです。(逆の場合はSim内のラグ等でそうなってしまっています。何度か試してみてください)

さいごに

ここで今回のおさらいをしてみましょう。
  1. スクリプトはオブジェクトに「機能」を与えるもの。
  2. LSLは3つの層でできている。「ステート」と「イベント」と「関数」である。
  3. 関数は「動作」を示す。値はその詳細。
  4. イベントは関数を内包し、その関数を発動させる「条件」を示す。
  5. イベント内部には関数を複数いれることができ、上から順番に処理される。

今回使ったスクリプト一覧

イベント
  1. state_entry(){ }
ステートが開始したとき開始します。
  1. touch_start(integer total_number){ }
オブジェクトがタッチ(クリック)されたとき開始します。
関数
  1. llSay(integer channel,string message);
オブジェクトが、指定されたchannelでmessageと発言します。
  1. llShout(integer channel,string message);
オブジェクトが、指定されたchannelでmessageと叫びます。