LSL仕様メモ4 イベントchangedでllResetScriptを使う場合の注意点
2009 年 2 月 14 日 土曜日仕様というよりただ自爆しただけですが、少しハマってしまったのでメモ。
結論から先に述べますと、
イベントattachとオーナーが変わった際のllResetScriptを同じスクリプトに入れてはいけない
前提として、
- イベントstate_entryは、初めてスクリプトが実行された時に1回だけ働く。
- llResetScript()は、そのスクリプトをリセットする。
- イベントchangedにおけるif(change & CHANGED_OWNER){~}は、オーナーが変わった時に働く。
以上のLSLの基本的な動きがあります。
例えばstate_entry内にllGetOwnerを書き、オーナーのkey(UUID)を得てなにかしら動く仕組みのものを作る場合、人にそのオブジェクトを渡すとstate_entryはもう実行されないので以前のオーナーのkeyが残ったまま不都合な動作が起こります。
これを回避するのに3.で挙げたchanged内でオーナーが変わった時にllResetScript()を動かし、state_entryを再度走らせてオーナーのkeyを取得し直す、というのがよくある手法です。
今回アタッチし機能するものを作っていたのですが、
- state_entry内に初回だけ働く機能を盛り込む
- attach内にアタッチするたびに働く機能を盛り込む
- changed内にオーナーが変わったらllResetScript
という組み合わせをしたところ悲劇は起きました。 (というほど大げさじゃないですが)
「付けてみたらちゃんと動かなかったけど、突然動くようになったよ」という理解不能なレスポンスのシロモノになってしまったわけです。
誤動作の流れとしては
- オブジェクトを渡した相手がアタッチする
- イベントattachが働く
- オーナーが変わったのでllResetScriptが働く
- イベントstate_entryが働く
となります。つまり、イベントattachで機能した内容がllResetScriptで消去されていました。
ちゃんとスクリプトを理解している人には当然なのでしょうが、自分はイベントchangedのif(change & CHANGED_OWNER){~}は、相手に渡した時点で機能すると勘違いしていました。
スクリプトなので当然Rez(アタッチも含む)されて始めて動くわけで、使用する人にオブジェクトを渡して最初の稼動がアタッチだと、イベントattach内の内容は全てキャンセルされてしまいます。
そして2回目アタッチした時は、オーナーが変わっていないのでllResetScriptは働かずattachは正常に機能します。途中からちゃんと動く不具合品の出来上がりですw
わかったつもりっていうのは危ないですね。基本的な機能でもテストしてからじゃないとダメだと思い知った件でした。