
2008年06月19日
衝突
ガードレールに衝突。
スカルプトテクスチャを切り替えて凹んだように見せるつもりなんですが、
ラグがあって最初の衝突ではしばらく丸くなってしまいます。
スカルプトは光源によってかなり色が変わるのも特徴ですね。
いいところでもありますが、意図しない色に見えてしまうことも。
色を白にして太陽光がまともにあたると白くなりすぎて、
ガードレールの溝が見えないこともあります。ちょっと灰色にした方がいいかもしれません。
何故かllPlaySoundを使うとスクリプトで記述していないところで、
音がなったりするので、最近はllTriggerSoundを使うようにしてます。

Video: Collision with guardrails in second life.
愛用のSciTEエディタのコンパイラは、
`PRIM_TYPE_SCULPT' is undeclared.
`PRIM_SCULPT_TYPE_CYLINDER' is undeclared.
などと言ってきて新しい定数に対応できてません。
開発はとまってるらしいので、LSLエディタに代えた方がよさそうです。
でも、なんか馴染んでしまってなかなか代える気がおきないんですよね。
スカルプトテクスチャを切り替えて凹んだように見せるつもりなんですが、
ラグがあって最初の衝突ではしばらく丸くなってしまいます。
スカルプトは光源によってかなり色が変わるのも特徴ですね。
いいところでもありますが、意図しない色に見えてしまうことも。
色を白にして太陽光がまともにあたると白くなりすぎて、
ガードレールの溝が見えないこともあります。ちょっと灰色にした方がいいかもしれません。
何故かllPlaySoundを使うとスクリプトで記述していないところで、
音がなったりするので、最近はllTriggerSoundを使うようにしてます。
Video: Collision with guardrails in second life.
愛用のSciTEエディタのコンパイラは、
`PRIM_TYPE_SCULPT' is undeclared.
`PRIM_SCULPT_TYPE_CYLINDER' is undeclared.
などと言ってきて新しい定数に対応できてません。
開発はとまってるらしいので、LSLエディタに代えた方がよさそうです。
でも、なんか馴染んでしまってなかなか代える気がおきないんですよね。
//guardrail.lsl
string defaultTex = "flat";
string crashTex = "crash";
string crashsound = "crashsound";
string curTex;
default {
state_entry() {
curTex = defaultTex;
llSetPrimitiveParams([PRIM_TYPE, PRIM_TYPE_SCULPT, defaultTex, PRIM_SCULPT_TYPE_CYLINDER]);
}
on_rez(integer int) {
llPreloadSound(crashsound);
}
collision(integer num_detected) {
if (curTex!=crashTex) {
curTex = crashTex;
llSetPrimitiveParams([PRIM_TYPE, PRIM_TYPE_SCULPT, crashTex, PRIM_SCULPT_TYPE_CYLINDER]);
llTriggerSound(crashsound,1.0);
// llSay(0,"collision");
}
llSetTimerEvent(10);
}
timer() {
curTex = defaultTex;
llSetPrimitiveParams([PRIM_TYPE, PRIM_TYPE_SCULPT, defaultTex, PRIM_SCULPT_TYPE_CYLINDER]);
llSetTimerEvent(0); //おっと忘れてた
}
}
2008年04月22日
リンク番号と名前を調べるスクリプト
20個ぐらいまでならなんとかリンク番号が狂わないように編集できますが、
いっぱいになってくるとそれもなかなか大変です。
リンクオブジェクトの場合は、0番はないのでNULL_KEYが帰ってくるようです。
(0 means no link, 1 the root/parent, 2 for first child)
1番から始まるので、
終了判定を
i < llGetNumberOfPrims()
とせずに
i <= llGetNumberOfPrims()
としないとだめなようです。
例)
[6:48] Object: 0) 00000000-0000-0000-0000-000000000000
[6:48] Object: 1) WittyRadarM24
[6:48] Object: 2) Map
[6:48] Object: 3) Approach
[6:48] Object: 4) TargetNameDisplay05
いっぱいになってくるとそれもなかなか大変です。
リンクオブジェクトの場合は、0番はないのでNULL_KEYが帰ってくるようです。
(0 means no link, 1 the root/parent, 2 for first child)
1番から始まるので、
終了判定を
i < llGetNumberOfPrims()
とせずに
i <= llGetNumberOfPrims()
としないとだめなようです。
//CheckLinkName.lsl
default {
state_entry() {
integer i;
for (i=0; i<=llGetNumberOfPrims() ;i++) {
llOwnerSay((string)i+ ") " + llGetLinkName(i));
}
}
}
例)
[6:48] Object: 0) 00000000-0000-0000-0000-000000000000
[6:48] Object: 1) WittyRadarM24
[6:48] Object: 2) Map
[6:48] Object: 3) Approach
[6:48] Object: 4) TargetNameDisplay05
2008年02月24日
デバッグ用のsay
オブジェクトの中にいくつかスクリプトを入れていると、
どれがsayしてるのか分からなくて困ることがありました。
それに不要になったときsayがデバッグ用のものなのか確認しながら、
最後には削除するわけですが、この関数でデバッグ用のsayをしておくと楽に検索できます。
llGetScriptName関数で得たスクリプト名とデバッグ用の文字をくっつけてsayします。
最初の変数debugmodeでスクリプトごとにデバッグ用表示をするかどうかを決めます。
デバッグ用のsayでは、多くのメッセージがチャットウィンドウに流れて
llSayだと迷惑がかかるので、llOwnerSayを使ってます。
しかし、最初にできるスクリプト「Hello, Avatar!」なんですが、
あれってllOwnerSayを使うべきだと思うのですが。
始めたころllSayばっかり使って、かなりスパムをばらまいてました。
ごめんなさい。
// スクリプト sayDebug
どれがsayしてるのか分からなくて困ることがありました。
それに不要になったときsayがデバッグ用のものなのか確認しながら、
最後には削除するわけですが、この関数でデバッグ用のsayをしておくと楽に検索できます。
llGetScriptName関数で得たスクリプト名とデバッグ用の文字をくっつけてsayします。
最初の変数debugmodeでスクリプトごとにデバッグ用表示をするかどうかを決めます。
デバッグ用のsayでは、多くのメッセージがチャットウィンドウに流れて
llSayだと迷惑がかかるので、llOwnerSayを使ってます。
しかし、最初にできるスクリプト「Hello, Avatar!」なんですが、
あれってllOwnerSayを使うべきだと思うのですが。
始めたころllSayばっかり使って、かなりスパムをばらまいてました。
ごめんなさい。
// スクリプト sayDebug
integer debugmode = TRUE;
sayDebug(string s) {
if(debugmode) {
s = llGetScriptName() + ":" + s;
llOwnerSay(s);
}
}
default {
touch_start(integer total_number) {
sayDebug("HELLO!");
}
}
2008年01月12日
自爆スクリプト
スクリプトコードの<>をエスケープするの忘れててあわてて直しました。
作ったオブジェクトを消すとき普通は、
1.Takeする
2.削除する
3.ゴミ箱から除外する
と3つの手順が必要ですが、これがとても面倒です。
しかも、持ち物のインターフェイスが反応が遅くてたまりません。(物が多すぎるのかな・・・)
それで、スクリプトを調べているうちにすぐに抹消する命令がありました。
llDie()という関数なのですが、ちょっと工夫してオブジェクトにドラッグしてクリックしたら抹消できるスクリプトを作りました。
このスクリプトですが、持ち物の中に作ります。「作成」>「新しいスクリプト」をクリックします。

Scriptsフォルダに「New Script」ができてます。

これをリネームして、「TouchToDieWithDialog」とします(なんでもいいですけど)。

それで、自動作成されたスクリプトを消してさっきのコードをコピペして、保存します。「Compile successful!」と下の欄に表示されたら完了です。

これで準備は完了です。さぁ、試してみましょう。
さっきのスクリプトをオブジェクトにドラッグします。

クリックすると削除するかダイアログで確認してくるので、OKをクリックすると跡形もなく消えてしまいます。もうどこにもありません。

でも、modify可のオブジェクトにしかできませんけどね。
作ったオブジェクトを消すとき普通は、
1.Takeする
2.削除する
3.ゴミ箱から除外する
と3つの手順が必要ですが、これがとても面倒です。
しかも、持ち物のインターフェイスが反応が遅くてたまりません。(物が多すぎるのかな・・・)

それで、スクリプトを調べているうちにすぐに抹消する命令がありました。
llDie()という関数なのですが、ちょっと工夫してオブジェクトにドラッグしてクリックしたら抹消できるスクリプトを作りました。
// スクリプトTouchToDieWithDialog
integer dialogHandle;
integer ListenChannelDialog=10;
default {
touch_start(integer total_number) {
dialogHandle = llListen(ListenChannelDialog, "", llGetOwner(), "");
string mes = "Do you delete this " + llGetObjectName() + " really?";
llDialog(llDetectedKey(0), mes , ["<OK>","<CANCEL>"] , ListenChannelDialog);
}
listen(integer channel, string name, key id, string message) {
if (channel==ListenChannelDialog ) { //for llDialog
if (message == "<OK>") {
llOwnerSay( llGetObjectName() + " say \"Bye!\"");
llDie();
}
}
llListenRemove(dialogHandle);
}
}
このスクリプトですが、持ち物の中に作ります。「作成」>「新しいスクリプト」をクリックします。

Scriptsフォルダに「New Script」ができてます。

これをリネームして、「TouchToDieWithDialog」とします(なんでもいいですけど)。

それで、自動作成されたスクリプトを消してさっきのコードをコピペして、保存します。「Compile successful!」と下の欄に表示されたら完了です。

これで準備は完了です。さぁ、試してみましょう。

さっきのスクリプトをオブジェクトにドラッグします。

クリックすると削除するかダイアログで確認してくるので、OKをクリックすると跡形もなく消えてしまいます。もうどこにもありません。


でも、modify可のオブジェクトにしかできませんけどね。


