Adsense

2008年5月10日土曜日

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

前回からの続きで「その3」になりました。
チャットキーボードの次は立ち姿の AO (Animation Override) を、、、と思ったわけですが、スクリプト以前にポーズというものが面白くて、QAvimator などを使って自分でポーズや短いアニメーションを作ってみたりしました。ポーズは Free のものでも相当の数、そしてなかにはクオリティが高いものが出回っていて、Secondlife を始めたころはひとつひとつ試してみたり、「その1」でご紹介したジェスチャに登録して使っていました。

アニメーションとポーズ、、、これは同じものなんですよね。
そのあたりは「ポーズは腰が命 全4回」(笑 や 「QAvimator って面白い」のエントリの中で紹介しています。 QAvimator の使い方、bvh ファイルの作成とアップロードの方法からわかってきました。

でも、自分の作ったポーズ(つまり、フレームを 2 つしか使っていないループアニメーション)って切り替えると「パッ!パッ!」とそのポーズになって、それが「不自然」ということに最初は気が付いていませんでした。それに気が付いたのが Maitreya のポーズを試してみたときでした。

MaitreyaPose21
Maitreya - CCRunwayPose21

それはポーズというよりも、立派なアニメーションでした。

これ、フォトだとまったくわからないと思いますが、「きめのポーズ」になるまでの体の動きがものすごくしなやかなんです。そして、数秒たったら、また違うポーズに変化する、、、、というものもありました。

アニメーションを操る、、、という意味では、 AO を設定し使うためのツールが提供されているのでまずはそれを使いこなすことですね。 ZHAO (もしくは ZHAO-Ⅱ) というツールが Secondlife では有名です。
ZHAO の使い方はいろいろなブログやサイトで詳細に説明されているので割愛しますがポイントは、

1) 地面上に ZHAO を Rez します。装着したままだとアニメーションをドロップできません。

2) 編集から ZHAO の [コンテンツ] フォルダを開き、購入したアニメーションをドロップします。

3) Empty や Default といった名前のノードカードがあるので、それを開いて AO させたいセクション(Walking や Standing)の直後にアニメーションの名前を書き込みます。アニメーションのプロパティを開いて名前をコピーしてノートカードに貼り付けるのがいいでしょうね。

4) 上記の設定が終わったら Take して、HUD として装着したら LOAD というボタン(もしくはダイアログのボタン)を押してノートカードを読み込ませ、アニメーションを有効化させます。

実は ZHAO ってあまり好きじゃなかったんです。それは、機能うんぬん、、、というより見た目でした。後でわかるのですが、ZHAO はいろいろな人、ショップがカスタマイズして提供しているので、それぞれ見た目は結構変わるんですよね。
でも、Secondlife をはじめた時に最初に見たのが以下の左側、、、
0
向かって右側のは Maitreya で配られている ZHAO です。最初に Maitreya の ZHAO を使っていたら、自分で AO 作ろうなんて思わなかったかもしれません。ちなみに ZHAO-ll だとダイアログを使ったメニューになっていますね。
とりあえず Standing のアニメーションだけオーバーライドさせたかったので、そんなに難しくないかも、、と考え、前回ご紹介した方法で作ってみようと思ったわけです。でも、そんな単純なものではありませんでした。(笑
(やっと本題?)

AO させるには Permission が必須

はじめて ZHAO を使った時 (もちろんスクリプトの中なんて見ません(笑)) まったく意識していなかったのですが、アバターに対してアニメーションをスタートさせるときはかならず llGetPermissions ([修正] ごめんなさい。許可をもらうのは llRequestPermissions です。)を使ってアバターから「許可」をもらわないといけません。
タッチしてダンスを踊るタイプのものだと以下のようなダイアログを見たことがあると思います。
1
「て・に・を・は」がちょっとおかしいですが、オブジェクト 'MLDU' がアバターを動かそうとしていますがいいですか? と聞いているわけです。([追記] 誤解ありそうな表現なので追記します。アニメーションをスタートさせることだけではなく、停止するにもこのパーミッションが必要なことから、animate you の部分は「(停止を含めた)動作をつける」という意味だと理解してくださいね。)

海外のダンスホールやクラブだとダンスフロアに配置されているダンスボールに Sit (パイメニューでは llSetSitText を使って "Dance" になっていると思います) するものが多くて、このダイアログってあまりみたことがありませんでした。ZHAO の AO も自分に「装着」しているのでこのダイアログはでません。

そうなんです。Sit もしくは装着しているとスクリプトは Permission をもらったとして処理し、このダイアログは表示しないんです。
でも、スクリプトの中ではきっちりと llGetPermissions llRequestPermissions が使われています。

この省略はとっても合理的だと思います。Sit でアニメーションが開始されて「やめたいな、止めたいな」と思ったときは Stand Up すればいいわけです。HUD や Dance Ring の場合は 取り外せば いいわけですよね。(llGetPermissions llRequestPermissions におけるダイアログ・タイプの注意点(恐怖?)は後日に・・・)
このとき作成した AO Ball (また、、、小さな玉でした、、)のソースを今みると、、、、ひどい・・・(笑

自分だけ、かつ、装着での使用なので問題ないのですが、run_time_permissions で PERMISSION_TRIGGER_ANIMATION がとれてなければ「また」llRequestPermissions をやっていたり、、、自分専用だからいいけど、、ちょっと公開するにはあまりにひどいので、、、ポイントだけ。
自分専用単機能 AO ボールのポイントは

1. attach(key id) イベントで id が NULL_KEY でなければ処理をします。NULL_KEY の場合は「はずされた」という意味です。
2. その処理では
a) for 文と llGetInventoryName(INVENTORY_ANIMATION, i) を使ってコンテンツフォルダにあるアニメーションの名前をすべてリストにいれる。
b) llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION) を使ってアニメーション開始の許可を id (装着している Avatar ) に申請する。
3. 装着の場合は暗黙的に許可が下りるので run_time_permissions(integer num) のイベントでは llSetTimerEvent を使って、0.1 秒や 0.2 秒といった間隔のタイマーをかける。
4. イベント timer() の中では
a) llGetAnimation を使って現在動いている Animation を取得
b) 現在の Animation が "Standing" だったら Override したいアニメーションの名前を List から llList2String で取り出す。
c) llStartAnimation を使ってアニメーションを開始する。
d) 上記 a)b)c) の処理のあと一定間隔後に、llStopAnimation で現在動かしているアニメーションをとめて、次のアニメーションを List から取り出し、開始させる。
e) "Standing" の状態でなくなったら、即時に llStopAnimation でオーバーライドしているアニメーションを停止する。

こんなところでしょうか。
当時の恥ずかしいスクリプトは、、、結構強引(無駄)なことをやっていたりしてます。
相当悩んだのが 4-d の「一定間隔後に止める」だったと記憶しています。llSetTimerEvent で 0.1 - 0.2 秒で timer() イベントを開始させる、というのは「続けなければならない」わけですから、llSetTimerEvent を使って 20 秒後にアニメーションを止める方法は 1つのスクリプトの中、1つのステート (State: 通常は default ) の中ではできないわけです。

今だったら、llResetTimellGetTime もしくは llGetAndResetTime を使うのでしょうが、当時はそれらを知らなくて、たとえば 0.2 秒ごとに timer() が呼ばれるなら、そこでカウントをとっていって、カウント数 X 0.2 が 20 以上になったら、、、みたいな処理をしてました。@@

状態監視については、ZHAO および ZHAO (改)などはもっと手の込んだことをしているようです。 ZHAO のソースは見ていませんが、どうやら llGetAgentInfo や llGetAnimationList のほかに control などを使って状態を監視しているようです。

これで、Permission の取得とアニメーションの開始、停止の基本ができたので、ははん、、、これでダンス・アニメーションを扱うスクリプトも書けるかなぁ、、などと「安易に」ぼんやり思いながら クラブ雷神で踊っていたら LINZOO さんの「10人でいっぱいになっちゃう同期ダンスユニットはねぇ、、、もっとたくさんのひとが踊れるのほしいよね」という言葉を聞いて「作ってみるー」と言ってしまったのでした、、、。
続く、、、え?まだ続くの?笑)