2007年08月31日
苦戦中なのです・・・
ここ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
何を作ろうとしているかと言いますと、
「フルパーミッションでないアニメファイルを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
Posted by Willam7 Streeter at 12:35│Comments(4)
│スクリプト
この記事へのコメント
こんにちは。
大胆にザックリとこんな感じではどうでしょう。
パーミッションは一度取得しておけば大丈夫なのでアタッチのタイミングで一度だけにしてみました。
string animation_name;
integer counter = 0;
key agent = NULL_KEY;
default{
attach(key id){
if (id != NULL_KEY){ // アタッチしたときパーミッション取得
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
}else{
agent = NULL_KEY // デタッチしたらアニメ対象は存在しない
}
}
run_time_permissions(integer perm) {
if (perm & PERMISSION_TRIGGER_ANIMATION){
agent = llGetPermissionsKey(); // アニメさせる対象はこの人
}
}
touch_start(integer detected){
if(llDetectedKey(0) == agent) { // 触ったのはアニメさせる対象と同一人物
if (counter == 0){
animation_name = llGetInventoryName(INVENTORY_ANIMATION , 0);
if (animation_name != "") { // アニメ名が取得できたなら
llStartAnimation(animation_name); // 再生
}
counter = 1; // 次のタッチは停止よ
}else {
llStopAnimation(animation_name); // 停止
counter = 0; // 次のタッチは再生よ
}
}
}
}
SLにINして試したわけではないので、動かなかったら申し訳ありません。
大胆にザックリとこんな感じではどうでしょう。
パーミッションは一度取得しておけば大丈夫なのでアタッチのタイミングで一度だけにしてみました。
string animation_name;
integer counter = 0;
key agent = NULL_KEY;
default{
attach(key id){
if (id != NULL_KEY){ // アタッチしたときパーミッション取得
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
}else{
agent = NULL_KEY // デタッチしたらアニメ対象は存在しない
}
}
run_time_permissions(integer perm) {
if (perm & PERMISSION_TRIGGER_ANIMATION){
agent = llGetPermissionsKey(); // アニメさせる対象はこの人
}
}
touch_start(integer detected){
if(llDetectedKey(0) == agent) { // 触ったのはアニメさせる対象と同一人物
if (counter == 0){
animation_name = llGetInventoryName(INVENTORY_ANIMATION , 0);
if (animation_name != "") { // アニメ名が取得できたなら
llStartAnimation(animation_name); // 再生
}
counter = 1; // 次のタッチは停止よ
}else {
llStopAnimation(animation_name); // 停止
counter = 0; // 次のタッチは再生よ
}
}
}
}
SLにINして試したわけではないので、動かなかったら申し訳ありません。
Posted by Miz
at 2007年08月31日 15:40

Mizさんに教えていただけるとは・・・本当にありがとうございます!
動きました! しかも当初やろうとしていたHUDで!
さすがですねー。感激です。
どうもありがとうございました!
これでループアニメ用のボタンができましたので、1回で終わるアニメ用のボタンも用意し、実用的なHUDを作ろうと思います。
どうもありがとうございました。
動きました! しかも当初やろうとしていたHUDで!
さすがですねー。感激です。
どうもありがとうございました!
これでループアニメ用のボタンができましたので、1回で終わるアニメ用のボタンも用意し、実用的なHUDを作ろうと思います。
どうもありがとうございました。
Posted by William7 Streeter at 2007年09月01日 02:28
初めまして。
私も現在似たような悩みを抱えつつ、アニメーションHUDを開発中です^^
スクリプトに関しては超ド素人でして、Willam7やMizさんのブログを参考にさせて頂きつつ頑張っております^^;
上記スクリプト、大変参考になりました!
William7さん、Mizさんありがとうございました!
試作できましたら、是非一度見てもらいたいと思っております^^;
私も現在似たような悩みを抱えつつ、アニメーションHUDを開発中です^^
スクリプトに関しては超ド素人でして、Willam7やMizさんのブログを参考にさせて頂きつつ頑張っております^^;
上記スクリプト、大変参考になりました!
William7さん、Mizさんありがとうございました!
試作できましたら、是非一度見てもらいたいと思っております^^;
Posted by Geteee Gausman at 2007年09月26日 16:22
Geteee Gausmanさん
がんばってください。
私もまったくスクリプトは素人でしたから、
きっと粘ればなんとかなると思います。
がんばってください。
私もまったくスクリプトは素人でしたから、
きっと粘ればなんとかなると思います。
Posted by Willam7 Streeter
at 2007年09月26日 18:38
