Adsense

2008年5月12日月曜日

セカンドライフのアニメーションを操る その4

アニメーションを操る、、、ということでシリーズもの(?)になってしまいました。
前回からの続きです、、、

LINZOO さんお得意の「つぶやき」にまんまと引っかかり(笑)、でも、今考えると本当に「安易」にダンス玉を作るといってしまった、、、と思います。

同期ダンスの仕組みはおおよそ予想がついていました。ちょうど大運動会のイカロス順位表示スクリプトを作ったので、メッセージを使ったスクリプトの連携などをすでに経験していました。なので、当時のエントリにもあるように llMessageLinked で「これ踊って~」というメッセージを投げ、それを複数のスクリプトが拾って llStartAnimation を Avatar に対して行う、この繰り返しでしょう、、、くらいの理解でした。

ビデオ玉音楽玉もすでに作っていたので、複数の人がひとつのスクリプトを利用する問題点と対応方法、ダイアログの使い方、ノートカードの読み込ませ方などもある程度わかっていたつもりでした。

0
当時のビデオ玉のダイアログ

スクリプトでアニメーションを操作して、アバターにダンスやポーズをさせる場合、Permission が必要だという話しはすでに書きましたが、この permission 、、、ちょっと危険な香りがする function なんです。それと (複数の人を対象としたダンス・スクリプトとしては、、、逆にかなり難しいですが) 複数の人がひとつのスクリプトを使った場合の llRequestPermissions の動きって、ちょっとトリッキーなんです。すぐに気がつきましたが、アニメーションを操る上では理解しておかないといけないポイントがいくつかあります。


llRequestPermissions... 許可をするときは覚悟が必要?(かも)


llRequestPermissions を使ったスクリプトは実はこれが初めてではありませんでした。はじめて llRequestPermissions を使ったのは「詐欺スクリプト」を検証してみた時だったんです。

詐欺注意 2007年6月23日の投稿です。

お金に絡む Permission の場合はダイアログが黄色になる、、、みたいな改善がその後行われてきましたが、いずれにせよ、この llRequestPermissions によるいくつかの制御の許可 (自分たちにしてみれば制御権限の委譲) は結構慎重にならなくてはいけないのかもしれません。

たかがダンス、、、といっても、スクリプトの書きかたが十分でないと、、、ダンスがとまらない、、、なんてことになっちゃうんです。


ポイントを以下に列挙します。
1)llRequestPermissions でスクリプトが取得した「許可」は一番最後に許可したアバターのもの (許可を受けとったもの) だけが有効。それ以前に許可した人については忘れてしまいます。(笑

2)「アバターに動きをつける」というダイアログの意味はアニメーションを開始させる、のほかに「アニメーションを停止させる」の意味も含みます。

3)上記からアバターのアニメーションの「開始」「停止」の両方を制御するためにはダンスするアバター分のスクリプトが必要になります。(実はそれだけではなく、llSetTimerEvent と timer() を使うのであれば、個別にスクリプトを用意する必要があります。)

4)停止方法が明記されてなくてもメニューの「ツール」-「アニメーションをすべて停止」からダンスアニメーションを止めることができます。しかし、それは自分のビュワーで止まって見えるだけで、他の人のビューワーでは動いて見えています。アニメーションの処理はそれぞれのクライアント・ビュワーでの画像処理になっているようです。

5)「許可をするときは覚悟が必要」もしくはスクリプトを書くときに注意しなくてはならない理由は、一度もらった(与えた) llRequestPermissions への許可は、スクリプト・リセット、そのスクリプトが無くなる、もしくは SIM リスタートによる SIM の全スクリプトのリセット以外に取り消すことができません。

6)ダンスアニメーションの場合のほとんどは llStartAnimation / llStopAnimation を llSetTimerEvent を使って何度も開始させています。ですので、上述の4)の方法でダンスを止めても、また、ログインしなおしても、そのスクリプトが「許可」を保持し続けている限り(きちんとしたエラー処理をすればするほど)スクリプトによる「アニメーションによる制御」がスクリプトリセットまで続きます。

7)この状態になってしまったら、プリムと同じ SIM にいる時は、ほとんど「奴隷」状態です。。。(ローリング・リスタートの有難みが・・・)
Permission については、以下のスクリプトを試してみるとわかると思います。試す場合はダンスアニメーションをスクリプトがあるプリムのコンテンツ・フォルダにドラッグ&ドロップして、以下のスクリプトの "Clube Dance 4" を該当するアニメーションの名前にしてくださいね。

key avatarKey; //プリムにタッチしたアバターの Key を格納するための key 変数宣言
default
{
    state_entry()
    {
        llSetText("",<1,1,1>,0);
        integer handle = llListen(0,"",NULL_KEY,""); //あえてオープンチャンネルの 0 を使ってます。
        llListenControl(handle, TRUE); //上記の Listen を開始します。
    }
    touch_start(integer total_number)
    {
        avatarKey = llDetectedKey(0); //タッチしたアバターの Key を取得します。
        llSay(0, "Touched by "+llKey2Name(avatarKey)); //タッチしたアバターの名前を Say します。
        // タッチしたアバターにアニメーションのパーミッションの許可を要求してダイアログを表示させます。
        llRequestPermissions(avatarKey, PERMISSION_TRIGGER_ANIMATION);                   
    }
    run_time_permissions(integer perm) //パーミッションのダイアログへの返信のイベント
    {  // もし返答が「はい」(許可する)だったら、
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        { //プリムの上に現在パーミッションの許可をもらい制御可能なアバター名を表示
            llSetText(llKey2Name(llGetPermissionsKey())+" under control.",<1,1,1>,1);
            llStartAnimation("Club Dance 4"); //制御可能なアバターに対してダンスをスタートさせます。
        }
    }
    listen(integer chan, string name, key id, string msg)
    {  //この場合、オープンチャンネルの、そこにいる誰の発言でも、最初の 6 文字が /start だったら、
        if(llGetSubString(msg,0,5)=="/start")
        { // 発言した人が制御下にあるアバターのアニメーションを開始する、と言い、開始させます。
            llWhisper(0,llKey2Name(id)+" が "+llKey2Name(llGetPermissionsKey())+" のアニメーションを開始します。");
            llStartAnimation("Club Dance 4");
        } else if (llGetSubString(msg,0,4)=="/stop") // 発言の最初の 5 文字が /stop だったら、
        {  // 発言した人が制御下にあるアバターのアニメーションを停止する、と言い、停止させます。
            llWhisper(0,llKey2Name(id)+" が "+llKey2Name(llGetPermissionsKey())+" のアニメーションを停止します。");           
            llStopAnimation("Club Dance 4");
        }
    }
}

スクリプトを書く人は必ずアバターにアニメーションの開始・停止の機会を与えて、アバターが意図しないときに勝手にアニメーションを開始するようなことがないようにしなくてはいけませんし、利用するほうは、ダンスに限らず 「許可をする」系のダイアログの返信についてはよくよく考慮した上で返信([はい]を押す)をしたほうが良いでしょうね。

なので、海外に多い [Sit] タイプのダンスは安心ができる、、、と前の投稿で書きましたが、これはアニメーション停止の方法がわかりやすいだけであって、暗黙的ながらも上のスクリプト同様にパーミッションの許可を与えていますから、llSetTimerEvent を使った timer() によるアニメーション・コントロールをされてしまうと、、、、立ったにもかかわらずアニメーションが開始されてしまいます。

[追記] お金に関する PERMISSION_DEBIT はこの 「暗黙的許可」はありません。Sit しても Wear しても、今は黄色いおおきめのダイアログが表示されます。

と、、、パーミッションについてはこれくらいにして、、、(続く)