スクリプトで遊べ!


基本編

1.オブジェクトにスクリプトを組み込んでみる!

 まず、手始めとしてオブジェクトにスクリプトを組み込んでみます。

 オブジェクトを選択してNewScriptボタンを押すと、スクリプトの雛形が
 自動でできあがります。

 出来上がったスクリプトの中身を表示すると以下のようになっています。
 初期状態でも、ちょっとしたプログラムができています。

 スクリプトの基本としてはスクリプト内部の「default」内に動作させるプログラムを
 書き込んでいくという形になります。

 初期のサンプルのスクリプトは
 初期化処理(プリムを置いた時)で「HelloAvatar」と喋る処理と
 タッチ(プリムを触る)したときに「Touched」と喋る処理が
 すでに出来上がっています。

 ※つまり、プリムを出したときに準備すべき処理を"state_entry"に書き
  プリムを触ったときに動かす処理を"touch_start"に入れれば、ちょっとしたものなら
  簡単に動いてしまいます。


2.まずは簡単につくってみる。

 まずは、オリジナルのプログラムを書き換えてみます。
 最初は自動生成されたソースに付け加えるような感じで勉強していくと良いとおもいます。

 このプログラムはオブジェクトを地面に置くと回転を開始
 オブジェクトをクリックすると回転が停止する単純なプログラムです。
 回転は回転看板などで重宝します。

 

使用関数(オブジェクトの回転)
   llTargetOmega([回転の指定] ,[回転の計算] ,[ゲイン]);
回転の指定:
  回転する方向と、速さを指定します。
  回転の値は少数点も指定できます。
  <[x座標],[y座標],[z座標]>

  例)横回転、回転の速さは0.2
    llTargetOmega(<0,0,0.2>,PI,1.0);
回転の計算:
  Radianの指定のようですが、普通は考えなくて良いです(PIのままでOK)
  値を大きくすると回転がカクカクに見えてしまいます
  (回転するときの回転角度指定のようです。)
ゲイン:
  特に値を変えても変わりません。名前的に明るさが変わりそうですが・・・
  これについては分かり次第更新します。

3.値を使いこなせ(変数)

 プログラムを作る上で必ず必要になる値の持ち方です。
 例えば計算や時間がきたら、なにかをさせたい等の条件付けの動作をさせる為には
 かならず値を持たなくてはなりません。
 今回は簡単にオブジェクトをタッチすると値が加算されていき、
 文字でその値を表示するプログラムを紹介します。

使用関数(文字の表示)
   llSetText([表示する文字] ,[色] ,[アルファ]);
表示する文字:
  表示する文字を指定します。
  この値はサンプルのようにstring形式の値を渡す場合と
  「""」で囲んで値を設定する方法の2通りがあります。

 例)「TEST」という白い文字を表示する
  llSetText("TEST", <1,1,1>, 1.0);
色:
  文字の色を指定します。指定できる色の種類は以下の通りです。
  <0,0,0>:黒 <0,0,1>:青 <0,1,0>:緑 <0,1,1>:水
  <1,0,0>:赤 <1,0,1>:紫 <1,1,0>:黄 <1,1,1>:白
  (小数点も指定できるので細かい色の調整もできます。)

 例)青い文字を表示する。
  llSetText("BLUE", <0,0,1>, 1.0);
アルファ:
  特に値を変えても変わりません。これについては分かり次第更新します。

 

変数
 integer 数字型の値を入れるための宣言です。
この型で文字を宣言すると以後その文字に
数値を入れる事ができます。
 -65535〜65534までの値が設定できます。

 integer val = 10000;
 10000をvalという変数に入れます。
 string 文字型の値を入れるための宣言です。
この型で文字を宣言するとこの文字に文字列を入れる事が
できます。

また、文字列中に以下のコードを入れると改行等を
入れる事もできます。
 [\t]:4文字分の空きを追加します。
 [\n]:改行をいれます(2列の文字にするときなどに)
 [\"]:「"」を入れます。
 (「\」はゲーム内で「/」になります)

例)
 string text = "Hello\nFakefur";

  Hello
  Fakefur       となります。
 型変換 数字を文字にしたり文字を数字にしたりする場合に
つかう型変換方法です。

 integer val = 10000;
 string text;
 text =(string)val;

 textの値が文字列の10000になります。

   他にもたくさんありますが、この2つで殆どの制御はできてしまいます。


4.定期的に処理を実行したい(タイマ)

 プログラムを作る上で重要な一つにタイマイベントという物があります。
 タイマイベントとは、プログラムにある一定間隔で処理を実行させたい場合に用います。
 通常は外部からアクション(タッチ等)をしなくてはいけませんが、
 これを使う事によってプログラムを自動的に動かす事も出来ます。
 (ちなみにここで使っている「Whistle call」はイベントリのライブラリフォルダに
  初めからあるサンプル音声です。)

使用関数(タイマイベントの開始(停止))
   llSetTimerEvent([時間(秒)]);
時間(秒):
 タイマの割込みを発生させる間隔を指定します。 単位は秒です。
 タイマの時間に到達すると「timer()」内のプログラムを実行します。
 なお、0を指定するとタイマを停止させることができます。

 例)
 llSetTimerEvent(10);
  10秒おきにタイマイベントが発生します。

 

使用関数(音声の再生)
   llPlaySound([名前],[音量]);
名前:
 再生する音声ファイルを指定します。

 例)
 llPlaySound("Whistle call",1);
 「Whistle call」という音声を再生します。
音量:
 音量のボリュームを指定します。 値の範囲は0〜1の様です
 (1以上を指定した場合は1に固定されます)

 注意!!:音声ファイルはスクリプトと同じようにオブジェクトの中に入れる必要があります。

 

使用関数(音声の停止)
   llStopSound();
再生中の音声を停止します。

ラグのせいか、即停止しないようです。

5.状況を判断して処理をしてみる(if文)

 if文はプログラムの動きを変化させるには欠かせない判断分岐命令です。
 このプログラムはタッチする度に違う色に変化するようにif文を使っています。
 (タッチする度に黒、赤、緑、青の順で色が変化します)

IF文
 if([条件]){        //判断1回目

  処理1

 }else if ([条件]){    //1回目が合致しなかった場合の判断

  処理2

 }else{           //すべて当てはまらない場合

  処理3

 }
if文(条件判断分岐)
条件が真(0以外)の場合処理を実行します。(わかりずら

簡単に言うと「条件」が成立した場合、直下の括弧内の処理を実行します。
条件の指定方法は以下のような種類があります。

値が同じ時: Number == 1   値が1になっている場合実行
値が違う時: Number != 1   値が1じゃない場合実行
以上判断:  Number >= 1  値が1以上の場合実行
以上判断:  Number <= 1  値が1以下の場合実行
(応用は山盛りありますがとりあえずこれを覚えれば大抵の事はできます。)

6.何回か繰り返して動かしたい(for文、do while文)

 タッチすると、赤色の数字を1〜10までカウントして
 カウントが終わると青色の数字を10〜1までカウントダウンします。

for文
 for([式]){

  繰り返し処理

 }
for文(ループ処理)
式で示した範囲の間処理を繰り返します。(式で使った値は保持されます。)

例)cntの値を0〜10までカウント。10になるまで繰り返します
 for (cnt = 0;cnt <= 10;cnt++){

   処理

 }

 

do while文
 do{

  処理1

 }while([値]);
do while文(条件判断付きループ)
値が真(0以外)の場合ループします。

簡単に言うと値が0以外であれば無限にループします。
内部の処理で値を0にするか、if文のように条件式をいれて値が一致すれば
ループから抜ける処理です。

値が同じ時: Number == 1   値が1になっている場合ループを抜ける
値が違う時: Number != 1   値が1じゃない場合ループを抜ける
以上判断:  Number >= 1  値が1以上の場合ループを抜ける
以上判断:  Number <= 1  値が1以下の場合ループを抜ける
(応用は山盛りありますがとりあえずこれを覚えれば大抵の事はできます。)

例)処理内でNumberの値を1にするとループを抜けます。
 do{

  処理

 }while(Number == 1);

例)処理内でNumberの値が0になるとループを抜けます。
 do{

  処理

 }while(Number);

 

使用関数(その場で指定した秒の間停止する)
   llSleep([値]);
プログラムを指定した秒数の間その場で停止させます。

例)5秒間停止する
 llSleep(5);

7.サブモジュールでプログラムすっきり

 プログラムが段々長くなっていくと、ごちゃごちゃしてしまってわかりづらくなってきます。
 また、全く同じ処理を複数の場所で使う場合はサブモジュールを作って置くと、
 その要所要所でその下位モジュールを呼ぶ1行を書くだけで済みますので
 とてもソースが見やすくなります。
 今回は項6で紹介したfor文とwhile文を切り分けてみます。

サブモジュール
 integer ColorCnt1(){  }

文字をカウント(1→10)する部分をサブモジュール化しました。
サブモジュール名は「ColorCnt1」です。
この定義の前に付いているinteger(数値型)は処理が終了した時に
結果の値を取り出すことができるようにする為です。
※ちなみになにも値を返さない場合はinteger等つける必要がありません。
 また、string等の違う型の値も返す事ができます。

演算結果をセットして終了する場合はreturn [値];を使います。
(この命令はかならず処理の最後に設定します。)
※値を返さない設定の場合はreturnは不要です。
サブモジュール
 ColorCnt2(integer Val){  }

文字をカウント(10→0)する部分をサブモジュール化しました。
サブモジュール名は「ColorCnt2」です。
この定義の括弧の中に入っているinteger Val(数値型)は処理を
開始したときに外部から値を渡す為の物です。

なお、このモジュールは名前の前に型の宣言がありませんので
return文は不要です。

応用編

8.音を連結させてみたい

 ゲーム内で通常音楽を流す場合は土地を所有してストリーム(これは他で説明します。)を
 設定する必要があります。
 しかし、それだけでは面白くありませんのでスクリプトで音楽を流す事もできます。
 音声ファイルのアップロードには制約があり、44kの最大10秒間の音声しか
 アップロードできないので、プログラムで結合して長い音楽を流します。
 ※音声ファイルは、「4.定期的に処理を実行したい(タイマ)」と同じように
  オブジェクトに入れてください

使用関数(音声の再生)
   llPlaySound([名前],[音量]);

名前:
 再生する音声ファイルを指定します。

 例)
 llPlaySound("Whistle call",1);
 「Whistle call」という音声を再生します。
音量:
 音量のボリュームを指定します。 値の範囲は0〜1の様です
 (1以上を指定した場合は1に固定されます)
使用関数(処理の停止)
   llSleep([時間]);
時間:
 その場で停止する時間(秒)を指定します。

 タイマとは違いプログラムをその場で一定時間停止させます。
 タイマ割込は指定時間になったらその状態を把握し
 プログラムをタイマの処理へ移動させるという多くの手順を取る為
 殆ど気になりませんがほんの僅かの時間に誤差が発生します。

 しかしこの命令はその場で止まり、時間が来たらすぐ次の処理を動かす
 という方法を取る為、誤差が少なくなります。
 音楽の結合等のシビアな処理にはこれを使うと良いでしょう。

 ちなみに10秒区切りの音楽に対しサンプルは9.9秒停止となっています。
 これはllPlaySoundの関数を実行しても即時に音が鳴り出すわけでは
 ない
ので、再生がスタートするまでの間を埋める為に9.9秒にしています。

9.ポーズを取らせて見る

 ポーズボールポーズスタンドを作る場合に使えるスクリプトです。
 なるべくシンプルにする為にオブジェクトの上でポーズを取る程度の物になっています。
 (サンプルソースを改造して使いやすくしました(笑))
 ※指定するポーズは「4.定期的に処理を実行したい(タイマ)」と同じように
   オブジェクトに入れてください

 ちょっとわかりずらいソースなので簡単に解説すると
 @state_entry
  ここでメニュー上に「Sit」と書かれている文字を「Pose」と変えます。
  また、ターゲットの上に座る(ポーズする)座標を設定します。
 Achanged
  状態が変わると発生するイベントです。まず、Sitを行った人のIDを取り出します。
  そのIDはSitをしたのか、Standupしたのかの判断に使います。
  IDが無い状態で新しくIDが取得できた場合はSitと判断してイベントを発生させます。
  IDがすでにあり、新しくIDが取得できない場合はStandUpと判断してリセットします。
  (すでにオブジェクトの上にいないのでIDが取れませんから)
 Brun_time_permissions
  Sitしたと判断しイベントを発生させるとここに来ます。
  通常のSitアニメーションをキャンセルして、設定したポーズのアニメーションを
  スタートします。
  (さっぱりな方は上の方の「SitAnimeName」を変えるだけでも使えますのでガンバッテw)

使用関数(メニューのSitを違う文字にする)
   llSetSitText([メニューの表示名]);
メニューの表示名:
 オブジェクトを右クリックしたときに出るメニューの「Sit」を他の文字に
 変更したい場合、ここの値に表示名を設定します。
使用関数(Sitした時の座標を指定する)
   llSitTarget([座標],[方向]);
座標:
 Sitした時にSitの場所の座標です。(X,Y,Z) 
方向:
 回転方向を指定します。(X,Y,Z,S)
 特に気にしない場合はZERO_ROTETIONで良いと思います。
使用関数(Sitした人のKEY番号取得)
   [キー] = llAvatarOnSitTarget();
キー:
 Sitした人のKey(ID番号)を取得します。
 座った人が誰なのか等の判断に使えます。
 取得に失敗(居ない)した場合はNULL_KEYを返します。
使用関数(Permissionsイベントを発生させる)
   llRequestPermissions([キー],[内容]);
キー:
 Key(ID番号)を指定します。
内容:
 発生させるイベントの種類を設定します。
 (この値はrun_time_permissionsのparmに受け渡され
  そこからの判断に使用できます。)

パラメータ詳細
 ・PERMISSION_DEBIT
  マネーボールなどのお金を配布する時などに使うイベント番号
 ・PERMISSION_TAKE_CONTROLS
  TakeやReleaseをする時などに使うイベント番号
 ・PERMISSION_TRIGGER_ANIMATION
  アニメーションをスタート/ストップする時などに使うイベント番号
 ・PERMISSION_ATTACH
  装備品をつけた時などに使うイベント番号
 ・PERMISSION_CHANGE_LINKS
  リンク処理などに使うイベント番号
 ・PERMISSION_TRACK_CAMERA
  カメラの位置情報を取る時などに使うイベント番号
 ・PERMISSION_CONTROL_CAMERA
  カメラの位置を変える時などに使うイベント番号
使用関数(指定したアニメーションの動作を停止する)
   llStopAnimation([名前]);
名前:
 停止したいアニメーション名
使用関数(指定したアニメーションの動作を開始する)
   llStartAnimation([名前]);
名前:
 動作させたいアニメーション名
使用関数(スクリプトの動作をリセットする)
   llResetScript();
 スクリプトの状態をすべてリセットして
 初期状態から開始したい場合に使います。

10.目的地を表示させたい(テレポート)

 目的地へ誘導したい場合はマップ上にマーカを表示すると分かりやすいです。
 タッチするとマップを開いて目的地を表示するスクリプトです。

使用関数(音声の再生)
   llMapDestination([目的地SIM],[目的地座標],[lookat]);
目的地SIM:
 マーカを表示する対象SIMの名前を指定します。
目的地座標:
 マーカを表示する座標を指定します。
lookat:未使用
 後のバージョンで追加されるようです。
 (一般的に目的地座標と同じ値を設定しているようです。)

そのほか、色々とOinariSIMの上空広場にサンプルも置いてあります。
興味のある方はお気軽にどうぞ。
但し、REZやMONEY系の使い方を誤ると問題が発生するような
サンプルプログラムは置いていません、あしからず。


注意&バグ

一部、スクリプトによっては異常な動作をするものがあります。

 @物理プログラム(衝突等でラグが発生)
    未検証(関数名も未調査)

 Aスクリプトが動いている状態でスクリプトファイルをデリート
  例えばテキストを表示しているスクリプトを実行したまま消したり
  ソースから処理をはずすとそのまま残って消えなくなってしまう場合も・・・
  もしそうなったら、オブジェクトをSHIFTを押しながら移動してコピーを作成し
  壊れてる方(移動した方が壊れたオブジェクト)を消せばリセットできます。

 B装備中のオブジェクトをEditで編集もできます。
  しかしEdit中の装備を外すとセカンドライフがフリーズ(動かなく)
  なってしまいます。(右上Xボタンで終了し再起動しないと復帰できません)

 ※スクリプトを組む上で問題や異常動作などいろいろ分かってくると思います。
  同ようにスクリプトを勉強して行こうとする仲間同士で情報の交換をしながら
  どんどん技術を発展させていけたらと思います。
  いずれはみんなで協力してなにかすごいものを開発したいですね(笑