llGetOwner() について

llGetOwner() について

- Xpyoda Janus の投稿
返信数: 4

LSL Portal Wikiで、llMoveToTarget()をしらべてました。

http://wiki.secondlife.com/wiki/LlMoveToTarget

そのWikiページに、オーナーの周りにオブジェクトが寄って来るようにするというスクリプトのExampleがありました。
これを自分のオブジェクト(NeXTcube のテクスを貼った箱)にいれて動くようにしたものを人にあげました。
そうすると、あげた人ではなく私のほうに寄ってくるようになってしまいました...。
「やっぱり、オーナーになついてるのね...www」とは言われたんですが、意図している動作とは違うので、バグです。

で、このバグの原因が llGetOwner() の使い方にあると分ったので報告です。
llGetOwner()のWikiのCaveats(警告)には、

When the owner of an object changes, code that depends on this function's return value will not automatically update for the new owner or be automatically re-evaluated.
...
オブジェクトのオーナーが変わっても、この関数の戻り値に依存するコードは、新しい所有者に対して自動的に(値が)更新されたり、再評価されたりはしません。
...

とあります。つまり、llGetOwner()実行して、その値でlisten系、request系、permission系のイベントをまっているようなものは、オーナーが変わったからといって、自動的に新しいオーナーでイベントが発生したりと更新はされないということです (詳細はllGetOwner() のWikiをご覧ください)。

スクリプトのExampleも、これが引き起こすバグにハマってました。これを解決するには、現在のイベントステートに changed()イベントを追加し、オブジェクトのオーナーが変わったら、強制的にリセットし、再評価するようにすれば良いです。

 

default
{
    ...
    changed(integer change)
    {
        if (change & CHANGED_OWNER) {
            llResetScript();
        }
    }
}


コンパイルしなおせば動くようになるようなスクリプトは、この配慮がされてないのかもしれません。
私も、いままでに作ったものは見直したほうがいいなぁ...と思ってます。

まあ、割と、「あるある」かもしれないし、ハマる人が減るといいかもしれないので、報告いたします。

Xpyoda Janus への返信

Re: llGetOwner() について

- Shinobar Martinek の投稿

on_rez でスクリプトをリセットすることでいいのでは。

on_rez(integer param)
{
    llResetScript();
}

誰かに渡すときは、いったんそのアバターのインベントリに入り、使うときに Rezするのですから。

Shinobar Martinek への返信

Re: llGetOwner() について

- Xpyoda Janus の投稿

ほとんどの場合、on_rez()でいいですね。

llGetOwner() のWikiにも書いてありましたけど、「..より信頼できるのは changed イベントを利用することです。...」とありましたので、深く考えず、それを使ってみたのでした。

で、ここで、on_rez()が発生しないで、オーナーが変わっるって状況ってどんなのがあるのだろう.....気になるぅーーー....と夜も眠れなくなりそうになった? ので確かめてみました。次のスクリプトをいれた、フルパーのオブジェクトをまず作ります。

default
{
    on_rez(integer start)
    {
        llSay(0, "プリムがRezされました");
    }

    changed(integer change)
    {
        if (change & CHANGED_OWNER) {
            llSay(0, "プリムのオーナーが変更されました。");
        }
    }
}

Aのアバターが作成した、このオブジェクトを地面に置いている状態で、Bのアバターがオブジェクトを選択して複製すると、changedイベントだけが発生します(on_rezイベントは発生しません)。
オブジェクトを複製するというのは、具体的に言うと、[制作]-->[制作ツールを選択する]--[編集ツール] (ショートカットキーCTRL+3)で、編集ツール を出して、対象オブジェクトを選択してからSHIFTキー押しながら移動する操作の事で、移動元にコピーされたオブジェクトが残ります。このコピーされたオブジェクトのオーナーは、Bのアバターになります。

他にも、on_rez()が発生しないで、オーナーが変わる状況というのがあるのかもしれませんが、まあ、特殊な状況なので、ほとんどの場合は、on_rez()でいいのだと思います。

Xpyoda Janus への返信

Re: llGetOwner() について

- yin chang (infrared Razor) の投稿
あと、オブジェクトが置かれたままで「実物を購入」した場合、REZなしでオーナーが変わるんじゃないかと思います。
むかーしSLで建築家さんが依頼受けて建てた建物を納品する際、その辺がらみでセキュリティーシステムが誤作動した、って話を聞いいたことがありますー。
yin chang (infrared Razor) への返信

Re: llGetOwner() について

- Xpyoda Janus の投稿

やってみました。

オブジェクトの編集ツールで、販売対象にオリジナルを選択し販売のチェックをいれると、インベントリに入ることなく、その位置に存在するまま、所有者が変わりました。この場合、changedイベントだけが発生し、on_rezイベントは発生しませんでした。

オリジナルを販売

 

たしかに、建売の家オブジェクトの販売とかだと、その位置にあるまま、所有者が変わった方が、再度配置し直さなくていいですからね。

勉強になりましたー。