スクリプトの最近のブログ記事

苦戦中なのです・・・

| コメント(4) | トラックバック(0)

ここ2週間くらい、スクリプトと格闘しています。

何を作ろうとしているかと言いますと、
「フルパーミッションでないアニメファイルを1クリックで動かすツール」
です。

といいますのも、最初から入っているアニメやフリーで売っているようなフルパーミッションのアニメはゼスチュア登録するなど、1つの動作で簡単に再生できますが、そうでないものは、いちいちインベントリーからダブルクリックで開き、さらにダイアログでクリックしなくてはいけません。

私の売っている空手アニメも、1クリックでバシバシと使えた方が楽しいに違いないのですが、今のSLの仕様ではそれができません。

ということで、
「フルパーミッションでないアニメファイルを1クリックで動かすツール」
を作ろうと思った次第です。

と言いましても私、スクリプトを書くのはまったく素人で、「できれば避けて生きていこう」と思っていました。
ゼロから自分で作るのはさすがに無理な気がするので、人様のサイトを探し歩いてみました。

で、見つけたのがご存じ「Makapu」、の中の以下のページです。
http://miz.slmame.com/e2514.html

この中で紹介されている以下のスクリプトを、まずはHUDとして使ってみようと思いました。
=====================================
string animation_name="boogie";
key agent = NULL_KEY;

default {
touch_start(integer detected){
if (agent == NULL_KEY) {
agent = llDetectedKey(0);
llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION);
}
}

run_time_permissions(integer perm) {
key perm_key = llGetPermissionsKey();
if (perm_key == agent) {
if (perm & PERMISSION_TRIGGER_ANIMATION){
key chk = llGetInventoryKey(animation_name);
list anms = llGetAnimationList(agent);
integer i;
for (i = 0; i < llGetListLength(anms); i++){
if (chk == llList2Key(anms, i)) {
llStopAnimation(animation_name);
agent = NULL_KEY;
return;
}
}
llStartAnimation(animation_name);
}
agent = NULL_KEY;
}
}
}
=====================================

HUDはとりあえずテスト用という事で、デザイン性は無視して以下の画面の右下のようなシンプルなものを用意しました


この緑の球のインベントリの中に、上のスクリプトと、テスト用のポーズアニメ(no copy, no mod)を入れ、1行目の"boogie"をポーズアニメの名前に変更します。

すると、おお、動きます。フルパーミッションでないアニメでもこれなら動きます。

でも、難点がいくつか・・・

1、アニメ開始する前に、必ずダイアログボックスが開き、クリックしてから動く。
2、本来はもう一度クリックするとループ解除されてポーズを止められるはずなのが、何度押しても止まらない。
3、複数のアニメを動かすために複数ボタンを持ったツールにしたいので、いちいち"boogie"を書き換えるのが面倒。

まず1、については、そもそもの趣旨からしてダイアログを毎回押すのであれば作る意味がないので、なんとか解決したいところ。で、あれこれ調べたのですが、あるサイトで、
「本人にアタッチした装備品の中のアニメであれば、ダイアログが出ない」
というようなことが書いてあったのを思い出し、背中にアタッチしたボールにスクリプトとアニメーションを入れたところ、ダイアログが出なくなりました。(画像の中の背中の球)

なるほど、HUDではないけど、アバターの背中をクリック、でコントロールするのも面白いかな、と、これはこれでOKと考えることにしました。邪魔ならボールを透明にしてしまってもいいし、いずれもっと恰好の好いものを作ってもいいし。


次に、2、ですが、どうしてこれが利かないのか分からず、あれこれ試したところ、フルパーミッションのアニメであれば機能することがわかりました。
あるサイト(すみません、どこだか忘れました)の記述によれば、

llGetInventoryKey(animation_name);

の関数は、インベントリ内(この場合、球のコンテンツ内)のアニメーションがフルパーミッションでない場合、NULLキーを返す、とのことでした。

そうすると、
if (chk == llList2Key(anms, i))
がいつまで経っても成立せず、ポーズを止められない、ということなのかな?と考えました。

で、動作中のアニメとインベントリ内のアニメを照合する、という方法をあきらめ、スイッチで切り替える方法を試そうと考えてみた次第です。

あと、3、についても、
llGetInventoryName
という関数で、インベントリ内のアニメの名前が取得できるらしいので、
animation_name = llGetInventoryName(INVENTORY_ANIMATION , 0);
という形で、球の中に置いたアニメの名前を自動的に取得できないかと考えました。

で、2と3の対応策を加え、さらに、背中の球を他人が触っても動作しないように
if(llDetectedKey(0) == llGetOwner())
を加えたのが、以下のスクリプトです。

===========================================
string animation_name;
integer counter = 0;
key agent = NULL_KEY;

default
{
touch_start(integer detected)
{
if(llDetectedKey(0) == llGetOwner()) //自分以外のタッチを受け付けない
{
animation_name = llGetInventoryName(INVENTORY_ANIMATION , 0); // インベントリ内の1つ目のアニメの名前を取得し、animation_nameへ代入
if (agent == NULL_KEY)
{
agent = llDetectedKey(0); // 触った人のキーを取得
llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION); //agentにアニメパーミッションを取得
if (counter == 0)
{
counter = 1;
}
else
{
counter = 0;
}
}
}
}

run_time_permissions(integer perm)
{
key perm_key = llGetPermissionsKey(); //変数perm_keyにパーミッション対象者のUUIDを代入
if (perm_key == agent) // agentとperm_keyが同じキーだった場合
{
if (perm & PERMISSION_TRIGGER_ANIMATION && animation_name != "")
{
if (counter == 1) //counterが1だった場合
{
llStartAnimation(animation_name); //animation_nameを実行
}
else //0だった場合
{
llStopAnimation(animation_name); //animation_nameを停止
}
}
agent = NULL_KEY;
}
}
}
=========================================

しかし、動かない・・・・・・・(涙)。

いろんなパターンを試したのですが、どうも、インベントリ内のアニメ名を取得できていなさそう・・・。

そして、その機能をはずして、手書きでアニメ名を書き込む形にしても、動かない・・・
ということは、if (counter == 1) を使ったスイッチも機能していない???

うーん、そろそろスクリプト素人としては限界か・・・

どなたか、アドバイスいただけませんでしょうか?

一応まとめますと、今残っている課題は・・・

2、本来はもう一度クリックするとループ解除されてポーズを止められるはずなのが、何度押しても止まらない。
3、複数のアニメを動かすために複数ボタンを持ったツールにしたいので、いちいち"boogie"を書き換えるのが面倒。

の2つです。

どうぞよろしくお願いいたします。。m( _ _ )m

公式サイト

筆者プロフィール

William7 Streeter

セカンドライフの中でアニメーションを販売しています。 昼は普通の会社員で、Web制作やCG制作の仕事をしています。 昔やっていた空手の経験を活かし、空手のアニメをたくさん作っています。