空飛ぶ絨毯(じゅうたん)の作成
スクリプトの基本的な作り方が分かったところで、何か面白いスクリプトの例として「空飛ぶ絨毯(じゅうたん)」を作ってみようと思います。これは、アバターが絨毯の上に座ると、アバターを乗せて空を飛ぶというものです。
実際に何か作ってみる前に、どうしたら、思い通りの動きができるのか考えてみます。ここで作る絨毯は以下のようなものです。
- アバターが絨毯に座ったら絨毯を空中に浮かせる
- タイマーを設定して自動的に少しずつ絨毯を動かす
- 絨毯を触ると、進行方向を90度変更する
- アバターが絨毯から降りたら絨毯を地上に降ろす
絨毯のプリム作る
まず、絨毯のプリムを作ってみます。ここでは、絨毯を、薄い板として作ります。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( 座標 )
座標の指定は、
llSetPos( <85, 220, 65> );
この命令だけを使えば、絨毯の移動ができそうに思いますが、絨毯を動かすのにあたって、このような絶対座標を指定してしまっては、絨毯を別の場所に設置するのが難しくなってしまいます。(実行するたびに同じ位置に戻ってしまいます。)
そこで、現在の座標を得ておいて、そこから相対的にいくらか移動することにすれば、絨毯を持ち運んでどこでも使うことができます。
プリムの現在の座標を得るには、「llGetPos()」命令を使います。例えば、プリムを空中に1m浮かせるには次のように書きます。
llSetPos( llGetPos() + <0, 0, 1> );
これで、プリムの移動方法が分かりましたので、アバターが絨毯を触ったときに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"); // 座った時の処理
}
}
}
}