2009年09月18日

カラーとテクスチャ両方をダイアログで指定

はじめましてm(_ _)mペコリ

最近になってLSLをやり始めてるんですけども…
リンクオブジェのカラーと、テクスチャをダイアログで変えれる様に書いてみたんですが…
個々に組み込むとちゃんと変わってくれるのですが、一緒に組み込むと、テクスチャはいいのですが、カラーの方がエラーを出してしまいます><;

良い解決法が有ったら、是非教えて頂きたく、投稿させてもらいましたm(_ _)mペコリ

ちなみに、↓のScriptを使っています。宜しくお願いします。

~~Collar Change Script~~
*親プリム*

list colors = [
"red", "green","blue",
"yellow", "pink","orange", "purple",
"grey","white","black"
];

list rgb = [
<1.0,0.0,0.0>, <0.0,1.0,0.0>, <0.0,0.5,1.0>,
<1.0,1.0,0.0>,
<1.0,0.3,0.6>, <0.936,0.504,0.0586>, <0.652,0.340,0.656>,
<0.5,0.5,0.5>, <1.0,1.0,1.0>, ZERO_VECTOR
];

integer handle;
integer channel=7;

default{
touch_start(integer detected){
if (llDetectedKey(0) == llGetOwner()){
handle=llListen(channel, "", llGetOwner(), "");
llDialog(llGetOwner(),"Select Color",colors,channel);
llSetTimerEvent(60.0);
}
}

timer(){
llSetTimerEvent(0.0);
llWhisper(0,"Time out! Touch again for change color.");
llListenRemove(handle);
}

listen(integer ch, string name, key id, string msg){
llSetTimerEvent(0.0);
llListenRemove(handle);
integer i = llListFindList(colors, [msg]);
if (i != -1){
vector c = llList2Vector(rgb,i);
llSetColor(c, ALL_SIDES);
llMessageLinked(LINK_SET, 0, (string)c, NULL_KEY);
}
}
}

*子プリム*

default {
link_message(integer sender_num, integer num,
string str, key id){
vector c = (vector)str;
llSetColor(c, ALL_SIDES);
}
}

~~Texture Change Script~~
*親プリム*

list Texture =
[
"BlackLeather","BrownLeather","white"
];
integer Handle;

default
{
touch_start(integer detected){
if (llDetectedKey(0) == llGetOwner()){
Handle = llListen(123, "", llGetOwner(), "");
llDialog(llGetOwner(), "Select texture", Texture, 123);}
}

listen(integer channel, string name, key id, string message)
{
llSetTexture(message,ALL_SIDES);
llSetLinkTexture(LINK_SET,message,ALL_SIDES);
llListenRemove(Handle);
}
}

*子プリム*

default
{
link_message(integer sender_num, integer num, string msg, key id)
{
llSetTexture(msg,ALL_SIDES);
}
}

Textureは、ダイアログボタンの名前と、Inventoryに入れてるファイルの名前は同じにしてます。

*エラーメッセージ*

Object: Could not find texture '<0.00000, 0.00000, 0.00000>'.
Object: Could not find texture '<1.00000, 1.00000, 1.00000>'.
Object: Could not find texture '<1.00000, 1.00000, 1.00000>'.
Object: Could not find texture '<1.00000, 1.00000, 1.00000>'.
Object: Could not find texture '<1.00000, 1.00000, 1.00000>'.
Object: Could not find texture '<0.00000, 0.50000, 1.00000>'.
Object: Could not find texture '<1.00000, 1.00000, 1.00000>'.
Object: Could not find texture '<1.00000, 1.00000, 1.00000>'.
Object: Could not find texture '<0.00000, 0.50000, 1.00000>'.
Object: Could not find texture '<1.00000, 1.00000, 1.00000>'.
Object: Could not find texture '<0.00000, 0.00000, 0.00000>'.
Object: Could not find texture '<0.00000, 0.00000, 0.00000>'.
Object: Could not find texture '<0.00000, 1.00000, 0.00000>'.
Object: Could not find texture '<0.00000, 0.00000, 0.00000>'.
Object: Could not find texture '<0.65200, 0.34000, 0.65600>'.



同じカテゴリー(スクリプト関連)の記事画像
オブジェクトのリンクとタッチで開く扉
自動チャットを止めたい
テレポートするとアニメーションが解除される
同じカテゴリー(スクリプト関連)の記事
 テクスチェンジのHUDについて (2015-07-01 04:51)
 モール用のプリムカウンターを探しています (2014-11-29 20:09)
 連続するアニメーションの処理 (2014-08-24 03:23)
 オブジェクトの上にフローティングテキストを出す。 (2014-08-22 16:46)
 チャットログの盗聴について (2014-02-03 03:43)
 椅子に座った後で位置調整できるスクリプト (2013-03-24 16:37)

Posted by みより  at 21:40 │Comments(10)スクリプト関連

この記事へのコメント
テクスチャ変更と、カラー変更のスクリプトファイルが別々になってるって事ですよね?

それを同じオブジェクトに入れた場合、タッチした時にダイアログが2つだぶりませんか?

エラーメッセージを見ると、テクスチャ指定(llSetTexture)のところにカラーデータが行ってしまってますね。


これは出来れば、ファイルはひとつにまとめて
メニューを以下のようにしてはどうでしょうか。


メインメニュー
「 color 」「 texture 」

「color」ボタンを押すとカラー選択メニューへ
「texture」ボタンを押すとテクスチャ選択メニューへ

階層分けすると複雑になりますが、使い勝手は良いと思います。


階層分けしたくなければ、カラーを一色減らして
ひとつのメニューにカラーボタン、テクスチャボタンを
並べてしまうというのも手っ取り早いやり方ですね。

ダイアログのボタンは12個までです。
Posted by Tako★MASARU at 2009年09月18日 22:47
>Tako★MASARUさん

ありがとうございますm(_ _)mペコリ

1つにまとめる事に気付かない、まだまだ初心者なもので^^;

段階分けで試してみます^^
Posted by みより at 2009年09月19日 09:50
もう解決なさったかもしれませんが・・・

スクリプトを拝見したところ、テクスチャの変更にllSetLinkTexture()を使用なさってますね。
llSetLinkTexture()はリンクしているプリムのテクスチャを設定する関数なので、子プリムのスクリプトでテクスチャ変更する必要はありません。つまり、子プリムのテクスチャ変更スクリプトを削除してしまえば正常に動くと思いますよ。
色変更のほうも、llSetLinkColor()を使えば同じように処理できます。子プリムのほうにスクリプトは必要なくなります。

タッチしたときに色変更とテクスチャ変更の両方のダイアログが出てしまうと思うので、スクリプトをひとつにまとめて、Tako★MASARUさんがおっしゃっているように階層分けなどで処理したほうがスマートですね。
Posted by あ at 2009年09月20日 08:45
他の方が言っているように、処理をひとつにまとめた方が良いかなと思います。
手順としては、

・最初のダイアログを表示
 「Texture」と「Color」というボタンをダイアログで表示

・listenイベント
 最初にタイマーを0.0に(タイマー停止)
 【以降、If構文】
 ★msgが「Texture」ならば、(if)
  「list Texture をダイアログで表示」
  「タイマー再設定」
 ★msgが「Color」ならば、(else if)
  「list colors をダイアログで表示」
  「タイマー再設定」
 ★上記以外の場合、(else)
  「リッスンを停止(llListenRemove~)」
  「msgがcolorsから選択したものか確認」(llListFindList(colors, [msg]))
  「colorsならば(if(i!=-1)~)色を変更」(llSetLinkColor(LINK_SET,~))
  「同様にmsgがTextureから選択したものか確認」
  「msgがtextureだった場合はテクスを変更」(llSetLinkTexture~)

必要な関数や、色・テスクチャの変更方法、ダイアログの表示などは全て現在のスクリプトに記述されているようなので、あとはそれの組み合わせで作ることが出来ますよ。
Posted by natsu at 2009年09月20日 11:22
>あ さん

コメント有難う御座います m(_ _)mペコリ

リンクプリム(合計18プリム)の一部のプリムは、カラー&テクスチャ変更をさせたくなかったので、変更させたい子プリムにScriptを入れて対応してます^^;

ダイアログ表示も、段階分けの対応に変更する事にさせてます^^
やっぱり、「スマート」にした方がいいですねw

>natsuさん

コメント有難う御座います ペコm(_ _;m)三(m;_ _)mペコ

flowchartがよく解って助かりました^^

現行のScriptの組み合わせで対応出来る様なので、やってみますw
Posted by みより at 2009年09月20日 12:37
llSetLinkTexture とllSetLinkColor は、リンクナンバーを元に個別にテクスチャ変更、カラー変更出来たと思いますよ。

現状では llSetLinkTexture(LINK_SET,・・・以下略)となってますが、LINK_SET の代わりに番号を入れるとその番号のプリムのみテクスチャが変わるという仕組みです。

llGetLinkNumber を使えばそれぞれの番号が分かりますが、調べるのが面倒な場合は一度リンク解除してから、プリムをひとつひとつリンクしていくと分かりやすいと思います。

ルートが1番で、あとは選択したのと逆の順番、つまり最後に選択したのがルートで1番という事になります。

ただし、あとからプリム追加したりとか、リンクし直すと順番変わってしまいますので注意が必要です。

ただ、ひとつのプリムだけ変更ならいいんですけど、数が多くなるとその分指定してやらねばならないのが面倒ですね。

llSetLinkPrimitiveParams を使えば一度に記述出来たかと思います。

http://wiki.secondlife.com/wiki/LlSetLinkPrimitiveParams

ただ、扱えるパラメータが多いので分かりづらいですね。
Posted by Tako★MASARU at 2009年09月20日 14:47
一部のプリムだけを変更したいんですね。
それならばちょっと手を加える必要が出てきますが、for文とlistを使って指定した番号のプリムだけを変更するようにすれば良いと思います。

色を変更したい場合の例を書いてみました。

★まず最初の方にリストを追加しておきます。
list prim = [1,2,3,4,6,10];//色を変更したいプリムのリスト

★色を変更する記述の箇所に、下のように書きます。

//メッセージ(msg)がcolorsリストにあるか判別
integer index = llListFindList(colors, [msg]);

if(i!=-1){
vector c = llList2Vector(rgb,index);
//forを使用して、primリストにあるプリムのみ色を変更
integer i;
for(i=0;i<llGetListLength(prim);i++){
llSetLinkColor(llList2Integer(prim,i),c,ALL_SIDES);
}
}

forの使い方については、こちらのサイトが参考になると思います。
http://www21.atwiki.jp/mizcremorne/pages/76.html#id_0762b78c

テクスチャについても同様にリストで指定した箇所だけ変更するようにすれば良いと思いますよ。

ただ、変更するプリムの数がとても多くなる場合は、リストから一つずつ順番に変更をしていくこのやり方では遅く感じることがあります。
その場合には、子プリムにscriptを入れる最初のやり方で、変更を行うのも一つの手段だと思います。

その場合はscriptが大量に入っているアイテムができることになりますので、必ずダイアログの操作などで全部のscriptを削除できる仕組みも入れておくことをお勧めします。

削除する流れは下記のような感じになると思います。

・「Delete」命令を親scriptから子プリムに送る
・子プリムのスクリプトは削除命令を受けたら自らを削除(llRemoveInventoryを使用)
・親script自身も削除

-----------------------------
ついでにですが、リンク番号を調べる方法です。
下のscriptを入れて、タッチするとその触ったプリムが何番目かわかります。

//Link number check
default{
touch_start(integer number){
llOwnerSay((string)llGetLinkNumber(0));
}
}
Posted by natsu at 2009年09月20日 17:15
すみません、↑の一部が書き間違えてました;

//メッセージ(msg)がcolorsリストにあるか判別
integer index = llListFindList(colors, [msg]);

if(index!=-1){// ←ここを修正
vector c = llList2Vector(rgb,index);
//forを使用して、primリストにあるプリムのみ色を変更
integer i;
for(i=0;i<llGetListLength(prim);i++){
llSetLinkColor(llList2Integer(prim,i),c,ALL_SIDES);
}
}

製作頑張って下さいね。
Posted by natsu at 2009年09月20日 17:17
>Tako★MASARUさん&natsuさん

色々と、アイデアを頂きまして、有難う御座いましたm(_ _)mペコリ
お陰様で、自分のイメージに添う形のScriptが完成しました\(^O^)/ヤッタァ

出来上がって記念に、貼って行きます^^
↓が、最終的に上手く作動したScriptです。

*親プリム*

list Menu =
[
"COLOR","TEXTURE"
];

list Texture =
[
"BlackLeather","BrownLeather","White"
];

list Colors = [
"red", "green", "blue",
"yellow", "pink", "orange",
"purple","grey","white"
];

list rgb = [
<1.0,0.0,0.0>, <0.0,1.0,0.0>, <0.0,0.0,1.0>, <1.0,1.0,0.0>, <1.0,0.0,1.0>, <1.0,0.4,0.0>, <0.501,0.0,0.501>, <0.6,0.6,1.0>, <1.0,1.0,1.0>
];

integer handle;
integer channel=1970;

default
{
touch_start(integer detected)
{
if (llDetectedKey(0) == llGetOwner())
{
handle=llListen(channel,"",llGetOwner(),"");
llDialog(llGetOwner(),"Please select main menu.",Menu,channel);
llSetTimerEvent(15.0);
}
}

listen(integer channel, string name, key id, string message)
{
llSetTimerEvent(0.0);
if (message == "COLOR")
{
handle=llListen(channel,"",llGetOwner(),"");
llDialog(llGetOwner(),"Please select changed colors.",Colors,channel);
llSetTimerEvent(15.0);
}

else if (message == "TEXTURE")
{
handle=llListen(channel,"",llGetOwner(),"");
llDialog(llGetOwner(),"Please select changed texture.",Texture,channel);
llSetTimerEvent(15.0);
}

else
{
llListenRemove(handle);

//color changer
integer i = llListFindList(Colors, [message]);
if (i != -1)
{
vector c = llList2Vector(rgb,i);
llSetColor(c, ALL_SIDES);
llMessageLinked(LINK_SET, 1, (string)c, NULL_KEY);
}

//texter changer
integer j = llListFindList(Texture, [message]);
if (j != -1)
{
string x = llList2String(Texture,j);
llSetTexture(x,ALL_SIDES);
llMessageLinked(LINK_SET, 2, x, NULL_KEY);
}
}
}

timer()
{
llSetTimerEvent(0.0);
llListenRemove(handle);
}
}

*カラー&Textureを変えたい子プリム*

default
{
link_message(integer sender_num, integer num,
string str, key id)

{
//color
integer a = num;
if (a == 1)
{
vector y = (vector)str;
llSetColor(y, ALL_SIDES);
}
//texture
else if (a == 2)
{
llSetTexture(str,ALL_SIDES);
}
}
}

*カラーだけ変えたい子プリム*

default
{
link_message(integer sender_num, integer num,
string str, key id)
{
//color
integer a = num;
if (a == 1)
{
vector c = (vector)str;
llSetColor(c, ALL_SIDES);
}
}
}

*Textureだけを変えたい子プリム*

default
{
link_message(integer sender_num, integer num,
string str, key id)
{
//texture
integer a = num;
if (a == 2)
{
llSetTexture(str,ALL_SIDES);
}
}
}

既存のままにしたい子プリムには、Scriptを入れないで対応しました。

Textureを変えたい子プリムには、親プリムと同じファイル名のTextureを入れてます。

色々と試した結果、llMessageLinked()を使って上手く作動して、エラーも出なくなりました^^
link_messageイベントの“sender_num”の部分に指定を入れて対応してます。

本当に、色々と有難う御座いましたペコm(_ _;m)三(m;_ _)mペコ
Posted by みより at 2009年09月21日 01:38
↑のコメで一部間違ってましたm(_ _)mペコリ

link_messageイベントの“sender_num”の部分ではなくて、“integer num”の部分です^^;
Posted by みより at 2009年09月21日 19:24
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。