Adsense

2009年9月27日日曜日

[LSL] シンプル ダンス アニメーション HUD :)

おひとりさま用 ダンス アニメーション HUD のお勉強用サンプルをかいてみました。

ものすごくシンプルな、HUD にあるダンスアニメーションをタッチするたびに切り替える、というものです。
ただ、アニメーションの操作(パーミッションやアニメーション名の取得)も重要ですが、スクリプトとかプログラミングのテクニックのお話しのほうも重要かもしれません。
HUD をタッチするたびにダンスを切り替える、、、というのは for 文による繰り返し処理に近いものがあります。こちらのブログの記事にもひさしぶりにスクリプトネタを書きましたが、複数のページをもつダイアログの処理も同じ考えかもしれません。

繰り返し処理の際にカウントする変数をうまく使って、1番目だったら、とか2だったら、というような数の指定を直接しない、、、ということですね。

MLDU (多人数高機能ダンスマシン?) などはすでに1つのプリムで何十ものスクリプト ファイルの連携で、何十人もの人とダンスを踊るものですが、スクリプト作成の最初の最初は以下のような 「おひとりさまダンスマシーン」 から出発するのでしょうね。
「おひとりさま」で HUD でしか使わない、という前提のダンス HUD のサンプルは以下のようになるのかな。

integer numOfAnims = 0; //HUDの中のアニメ数をいれる変数
string nowDancing = "";  //踊っているダンス名をいれる変数
integer danceIndex = 0; //何番目のダンスかをいれる変数(インデックス)

default{
    attach(key id){
        if(id!=NULL_KEY){ //NULL_KEYでなければ装着、NULL_KEYは取り外し
            danceIndex = 0; //インデックスを0に
            llSetText("",<1.0,1.0,1.0>,1.0); //HUDのテキストをクリア
            //attach イベントで取得した key を使ってパーミッションリクエスト
            llRequestPermissions(id,PERMISSION_TRIGGER_ANIMATION);
            //アニメーションの数を取得
            numOfAnims = llGetInventoryNumber(INVENTORY_ANIMATION);
            if(numOfAnims==0){ //アニメーションがないとき
                llOwnerSay("アニメーションがありません~。");
            }else{ //アニメーションがあったら
                llOwnerSay((string)numOfAnims+"個のダンスを使えます~。");
                llSetText("Dance!",<1.0,1.0,1.0>,1.0);
            }
        }else{
            if(nowDancing!=""){ //ストップするアニメーションがないときのエラー回避
                llStopAnimation(nowDancing);
            }
        }
    }
    state_entry(){
        llSay(0, "Hello, Avatar!");
    }
    run_time_permissions(integer perm){ //別注参照~とっても重要!
        if(perm & PERMISSION_TRIGGER_ANIMATION){ //暗黙の許可をもらう
            llOwnerSay(llKey2Name(llGetPermissionsKey())+" さん、タッチでダンススタート、さらにタッチで次のダンス、止めるときははずしてね。");
        }
        if(numOfAnims==0){ //アニメーションが無いときのメッセージ
            llOwnerSay("でも、その前にアニメーションをいれてね。");
        }
   }
   touch_start(integer total_number){
       if(numOfAnims>0){ //アニメーションがあるときだけタッチに反応
           if(nowDancing!=""){ //今踊ってるダンスをとめます。踊ってなければスルー 
               llStopAnimation(nowDancing);
           }
           if(danceIndex>=numOfAnims){ //インデックスがアニメ数以上のときは0に
               danceIndex = 0;
           }
           // HUD のインベントリから danceIndex 番目のアニメーション名を取得
           string s = llGetInventoryName(INVENTORY_ANIMATION,danceIndex);
           llStartAnimation(s); //アニメーション開始
           nowDancing = s;     //現在のアニメーション名として登録
           llSetText(s+" ("+(string)(danceIndex+1)+"/"+(string)numOfAnims+")",<1.0,1.0,1.0>,1.0);
           danceIndex++;
      }else{  //アニメーションがないのにタッチして踊ろうとしたときの対応
           llOwnerSay("アニメーションが入ってないから踊れないよ。");
      }
   }
}

これで何個アニメーションが HUD に入っていてもソースを変えることなくダンスを踊ることができます。
HUD の装着・取り外しで HUD 内のアニメの数が更新されます。

別注参照は、llRequestPermissions を使った場合は run_time_permissions イベントを使うことです。というのも、HUD のような装着や Sit などによるアバターへのリンクをしたプリム内スクリプトからのパーミッションリクエストは「暗黙の許可」を行いますので、run_time_permissions で本来ダイアログで表示する「許可するかどうか」の結果を確認しなくても llStartAnimation や llStopAnimation は動く(使える)のですが、それを知ってやっているのであればいいのですが、、、知らないと知っているのでは違いますからね。
暗黙の許可についてはこちらなどを参考に。

上記サンプル、そこそこエラー処理もしてますし、List を使わないのでメモリー不足になることもありません。

ただ、、MLDU などは細かいところでちょっと違う処理をしていたりします。そのあたりは過去のブログにチラチラ書いていたりします。
以上、おひとりさまダンス HUD のサンプルでした~。