08/10/09[]
JIRAにポストされた、state_entryの勘違いの例
08/10/04[]
「タイマーで指定した時間よりもかなり早くtiemrイベントが上がってくる」という報告があり、検証を行うためにそのスクリプトのタイマーの部分だけを切り出したスクリプトを見せてもらいました。
その検証スクリプトの構造は、以下のようになっていました。(説明用に簡易にしてあります)
default { state_entry() { llSetTimerEvent( 300 ); } timer() { llOwnerSay( "timer!" ); } }
この構造自体は非常にシンプルですね。 このスクリプトを入れたオブジェクトを販売して、購入した人が使用した時にtimerイベントが意図したよりも早く上がってくるということでした。
これは「仕様どおり」の動作です。
state_entryは、購入した人がそのアイテムをrezした時には発生しません。 もしrez時に必ずタイマーを初期化してスタートする必要があるなら、on_rezイベントをトリガーにして、スクリプトリセットかタイマーの初期化を行う必要があります。
「(defaultステートの)state_entryは、オブジェクトがrezされた時に呼び出されるイベントではない」ということを、周知する必要があるのかもしれません。
08/07/19[]
ある方からの質問で、「所有者の名前を取得するようにしているのに、誰が試してもスクリプト作者の名前になるのはなぜ?」というものがありました。
これは、スクリプトを見せていただいてすぐに原因が特定できました。
所有者の名前を取得する処理が、state_entry() の中にしか記述されていなかったのが原因です。
LSLスクリプトでdefaultステートのstate_entry()が実行されるのは、以下の状況です。
(話を単純にするため、また、一番勘違いされやすいのがdefaultのstate_entryであるため、ここではdefaultステートのstate_entryのみに話を限定します)
- スクリプトをコンパイルした後(スクリプトがリセットされる)
- スクリプトウィンドウでリセットボタンを押した
- その他明示的にスクリプトをリセットした
- バージョン1.21以降のクライアントで、Toolsメニューからスクリプトをリセットした場合等
- スクリプトによるリセット
- スクリプト内で、llResetScript() を呼び出してリセットした
- 他のスクリプトから、llResetOtherScript() によってリセットされた
- 別のステートから、defaultステートへ遷移した
- 同一ステート(この場合はdefaultからdefault)へ遷移した場合は、state_entryは呼び出されません
- スクリプトの入ったオブジェクトをコピーした時(コピーされて新しく出来た方)
- 自分のインベントリからプリム/オブジェクトにスクリプトをドロップした
- スクリプトから実行停止したスクリプトについて
- オブジェクトをtakeしてインベントリに格納後、それを再度rezして、スクリプトを実行状態にする
- SIMの再起動後、スクリプトを実行状態にする
これ以外の、たとえばスクリプトが入ったオブジェクトをRezしたり装着したり、他の人に渡したりした場合は、state_entry()はそのままでは呼び出されません。
Rezした場合であればon_rez、装着した場合であればon_rezとattachイベントが発生します。state_entryイベントは発生しません。
これはLSLで非常に勘違いされやすい仕様の1つのようです。
プリムコピー時の挙動に関する参考ページ
このページのTinyURL:http://tinyurl.com/SC-state-entry