スクリプトを勉強していて、何を考えていたとか、覚え書きのようにスクリプト関連の記事を残していくことにした。
街灯を作る必要ができて、手持ちのランタンのスクリプトから作ることにした。
llGetSunDirection
で、太陽の位置を調べて地平線(z=0)の上か下かで判断するらしい。LSL wikiのサンプルをみると
integer lightsOn = -1;//not TRUE or FALSE
CheckSun()
{
vector sun = llGetSunDirection();
integer turnLightsOn = (sun.z < 0);
if(turnLightsOn != lightsOn)
{
lightsOn = turnLightsOn;
llSetPrimitiveParams([ PRIM_FULLBRIGHT, ALL_SIDES, lightsOn ]);
}
}
となっている、integer lightsOn = -1;//not TRUE or FALSE integer turnLightsOn = (sun.z < 0);のあたりの処理の仕方がまだ理解できない、プログラマーじゃ無いし独学だからなーsun.zの値がマイナスの時だけ代入するの?それがlightsOnとへんかしてたら入れ替えてPRIM_FULLBRIGHTの最後の因数にあたえてオンオフできるの?マイナス値でいいのとかいっぱい疑問、ここはパスだな単純にif文でわけてオンかオフにしちゃおう。
これをタイマーを使って定期的にチェックすればいいのか、次の問題はサイクルだな何分おきにチェックすればいいのか?SLの一日は4時間らしい、また昼3時間夜1時間のくりかえしらしい、1時間に1回ぐらいでもいいとおもってたけど夜が1時間なので1分ごとに調べることにした。(実際は5分ぐらいでももんだいなさそう)。次はユーザーインターフェースだ(笑)、出来るだけシンプルにしたい、メニューなど使うと時間切れ処理とかめんどうなので、やめる。細かい数値の変更はスクプを編集可能にし先頭の変数の値を書き直してもらうようにする。ノートカードとか読み込まない(ただめんどうなだけ)。タッチするだけで、オートモード、オン、オフのトグルスイッチとする。タッチするたびに、stateで切り替えることで実現する。タッチイベントで次のstateに飛ばしちゃった方がかんたんだろうてかんがえた。さてあとは、ライトの点灯時の処理だね、テクスチャーをフルブライトにするのはサンプルにあるから、あとはグローとライトの設定も一緒にすることにする、カンマで区切って列記すればいいそうだ。そうそう、かってにいたずらされないように、タッチイベントをオーナーか同じグループの人に限定することにしよう。
以下 スクリプト (タブが消えて、すみません)
//=========================================================
//auto light script by Michie Yokosuka : 28-09-2010
//=========================================================
//
//==============================
//Light param
//==============================
vector Color = <1, 1, 1>;
float Intensity = 1.0;
float Radius = 7.0;
float Falloff = 0.75;
//==============================
//Glow param
//==============================
float Gintensity = 0.03;
//==============================
// Script variables
//==============================
integer lightsOn = FALSE;
//==============================
CheckSun()
{
vector sun = llGetSunDirection();
if ( sun.z < 0 && !lightsOn )
{
lightsOn = TRUE;
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, lightsOn,
PRIM_POINT_LIGHT, TRUE, Color, Intensity, Radius, Falloff,
PRIM_GLOW, ALL_SIDES, Gintensity ]);
}
else if ( sun.z > 0 && lightsOn )
{
lightsOn = FALSE;
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, lightsOn,
PRIM_POINT_LIGHT, FALSE, Color, Intensity, Radius, Falloff,
PRIM_GLOW, ALL_SIDES, 0 ]);
}
else
{
}
}
default
{
state_entry()
{
state autolight;
}
}
state autolight
{
state_entry()
{
llSay(0, "set Auto Light!");
CheckSun();
llSetTimerEvent(60);
}
touch_start(integer total_number)
{
if (llDetectedKey(0) == llGetOwner() || llSameGroup(llDetectedKey(0)))
{
llSetTimerEvent(0);
state lighton;
}
}
timer()
{
CheckSun();
}
}
state lighton
{
state_entry()
{
llSay(0, "light on!");
lightsOn = TRUE;
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, lightsOn,
PRIM_POINT_LIGHT, TRUE, Color, Intensity, Radius, Falloff,
PRIM_GLOW, ALL_SIDES, Gintensity ]);
}
touch_start(integer total_number)
{
if (llDetectedKey(0) == llGetOwner() || llSameGroup(llDetectedKey(0)))
{
state lightoff;
}
}
}
state lightoff
{
state_entry()
{
llSay(0, "light off!");
lightsOn = FALSE;
llSetPrimitiveParams([
PRIM_FULLBRIGHT, ALL_SIDES, lightsOn,
PRIM_POINT_LIGHT, FALSE, Color, Intensity, Radius, Falloff,
PRIM_GLOW, ALL_SIDES, 0 ]);
}
touch_start(integer total_number)
{
if (llDetectedKey(0) == llGetOwner() || llSameGroup(llDetectedKey(0)))
{
state autolight;
}
}
}
以上が出来上がったスクリプト
テスト後50行目あたりのCheckSun();を追加、夜間Rezしたとき、1分待たないと点灯しなかったため。とりあえずうまく動いてるみたいだ。出来上がった品は別の記事で。