• Announcements

    • Xiola Linden

      The New Community Platform   03/21/2017

      We are still working on making adjustments and changes to the new platform. Thanks  to everyone who has been sending in feedback and filing any bugs you've encountered! 
Sign in to follow this  
Followers 0
Syle Devin

HUD work separately for different objects?

17 posts in this topic

So I just accomplished creating an HUD that will select the different sections of an object for you and change there color. Right now it is made to work with furniture and the furniture listens for the HUD. This causes a problem when you have more than one furniture piece out because the HUD effects all furniture set up to work with the HUD. 

 I can only think of one way to do this and it is not prefered. I don't really want to make people click on the furniture but if I can somehow have a random channel be created when you click on the furniture and the HUD will read that and replace the channels that effect the color changing then I would be fine adding something like that. Is do able without much extra work and adding to the scripts I already have?

Though this can also be a problem because you can click on the furniture and choose what face you want to change the color of. I imagine with a click channel changer the channel would be changing constantly while your choosing your face. Would this be bad? If it isn't bad I might look into a click change but I'm trying to see if there is a better way to set up the scripts.

 

 Any suggestions on how I should go about making the HUD work seperately for different objects?

Share this post


Link to post
Share on other sites

I don't see clearly how you separate clicking the HUD and clicking the rezzed objects (furniture)

The most simple and straight forward way to separate objects would be by their object name
You can have a list of object names from which you pick the one you want
Using a sensor you can make a list if you don't want to make it manually
You would need a sensor anyway to make a list of object keys
With name and key lists at hand you can say your command to any specific piece of furniture by llRegionSayTo()

:smileysurprised::):smileyvery-happy:

Share this post


Link to post
Share on other sites

Hmm, sounds like I could do it tht way but hte only problem is that it involves having a set amount of items and there names. I want this to work with multiple items regardless of the quantity or names. One reason, but not the only, being that the objects will be modifyable and so the name might change.

 

That sensor is pretty interesting though, didn't know sensors were possible.

Share this post


Link to post
Share on other sites

But then that takes chat commands. Isn't there some way I can just have the HUD register the couch by clicking on it? I think it would be hard to code but I am up for it.

Share this post


Link to post
Share on other sites

You could do it all with dialogs, if you were clever enough. Tell your sensor to look for all objects within a 15m radius and put their names on dialog buttons.

Share this post


Link to post
Share on other sites

Interesting though  that would get me a bunch of objects that wouldn't be associated with the HUD? Would there be a way to keep that from happening? Maybe some sort of message and return message to associate certain objects with the HUD?

 

Also I am testing out my original idea. When you click on the furniture it sends out a message with a random whole number. The scripts will read that and then put it as the channel that they speak on. Though is it possible to set a random number as an integer to replace the listen channel?

Such as this? Though I am getting erros and I can't see why.

integer random;default{    state_entry()    {        random = (integer) llFrand (7.0);    }    touch_start(integer total_number)    {                llSay(PUBLIC_CHANNEL, random");    }}

 

Share this post


Link to post
Share on other sites

If you do that, just remember that a chat message is always a string, so you'll have to recast that integer variable to send it and then convert it back to an integer on the other end.  (Also, use a high negative number, not a positive number in the range from 0 to 6.)

Yes, doing a raw sensor scan would get you the 16 closest objects within range, not just your sofas.  You could always filter for objects named "Sofa" though, as in

llSensor ("Sofa","",ACTIVE|PASSIVE,15.0,PI);

or scan for everything but only make dialog buttons

if (~llSubStringIndex(llDetectedName(i),"Sofa"))

Share this post


Link to post
Share on other sites

Yea I was thinking about that, detect name or something, but if the user ever changes the name of the object and decides, for whatever reason, to remove sofa, then the HUD wouldn't work.

 

Also I am not sure what you mean by recast? I did manage to get the script working. I just changed it to

touch_start(integer total_number)    {                random = (integer) llFrand (-500.0);        llSay(PUBLIC_CHANNEL, (string) random);    }

 

Also is it possible to have listen look for a set of numbers or a (string) on a specific channel or would I have to set the script to listen for anything?

Share this post


Link to post
Share on other sites

hrm..mebbe this?

in your couch, add a few things

 

in state_entry....

        key myKey = llGetKey();
         vRed = <1,0,0>;

 

in the listen.....

 list cmd = llParseString2List(message,[" "],[" "]);
         if(llList2Key(cmd,0) == myKey)
         {
           string  newColor = llList2String(cmd,1);
             if(newColor == "red")
             {
             llSetColor(vRed, ALL_SIDES);

            }

       }

 

___________________________

 

in the HUD...

in the listen event...

 

key sendID = id;       

 

and in the HUD touch start.....

 

 llSay(-5256, (string)sendID + " " + color);

______________________________

each item has a key,,,,so you can respond to them

not by name, but by each individual object? 

 

Share this post


Link to post
Share on other sites

Ah ok wasn't sure if that was what you had meant Rolig. I did my best to look at teh syntax for llListen but I am not sure what to do as my string isn't specific. The only thing specific about them is that the number is negative and how many characters are in the number. Is that enough information to set a string for the listen to look for?

Share this post


Link to post
Share on other sites

How about a different approach?

You don't need, it seems to me, to have your furniture listening all the time, so I think it's going to be easier to wake up a particular piece of furniture when you want to recolour it, have it acknowledge that it's awake, and then have the hud grab the uuid when the furniture sends the acknowledgement  and use llRegionSayTo to colour it.

So, in the furniture,  something like

integer hud_channel;integer handle;integer offset = 99; //use an offset in case any other objects are generating channels by this methodkey owner;key toucher;default{	state_entry()	{		owner = llGetOwner();		hud_channel = offset+ ((integer)("0x"+llGetSubString((string)owner,-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;	}	touch_start(integer total_number)	{		toucher = llDetectedKey(0);		if(owner == toucher){// if my owner has touched me			llResetTime(); // zero the script time			llOwnerSay("hold the mouse key down for at least 1.5 seconds to activate the listener");			//this is for the purposes of an example.. probably you want to have the hud explain this to the owner in an real build		}	}	touch_end(integer total_number)	{		if((toucher == owner) && (llGetTime()>1.5)){ //if the mouse key was held down for more than 1.5 seconds			llRegionSayTo(owner,hud_channel,"hi!"); //acknowledge message, thus providing uuid			llListenRemove(handle);			handle = llListen(hud_channel,"","",""); //start listening for messages from the hud			llSetTimerEvent(30.0);		}	}	listen(integer channel, string name, key id, string message)	{		if (llGetOwnerKey(id)!=owner){			return;		}		llSetTimerEvent(30.0);		//do colouring stuff			}	timer()	{		llListenRemove(handle);		llSetTimerEvent(0.0);	}	}

 and, in the hud

 

integer hud_channel;integer handle;integer offset = 99; //use an offset in case any other objects are generating channels by this methodkey owner;key target;init(){	owner = llGetOwner();	llListenRemove(handle);	hud_channel = offset+ ((integer)("0x"+llGetSubString((string)owner,-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;	handle = llListen(hud_channel,"","","");}default{	state_entry()	{		init();	}	attach(key attached)	{		if (attached){			init();		}	}	listen(integer channel, string name, key id, string message)	{		if (llGetOwnerKey(id)!=owner){			return;		}		if ("hi!"== message){			target = id;			//now you've got the uuid, you can send commands using llRegionSayTo(target, hud_channel, "change cushions to blue");		}	}}

 

Share this post


Link to post
Share on other sites

Oh this is interesting because I originally had it set up that way without a custom channel. The couch would only listen when you touched it. This was before I had an HUD that you could choose which color you wanted. I'd have to see if I can make this work with the HUD buttons that you can also click to choose what furniture piece you wanted to edit. 

Thanks, I am going to work with that and see what I can come up with. 

Share this post


Link to post
Share on other sites

If I've properly understood you, you're using the hud to select the colour and the component (frame, upholstery, cushions... ) to which the colour is to be applied.

So how about, use the hud buttons to set the value of the string "strWhichPart" and then have the hud say to the furniture

llRegionSayTo(target,hud_channel, strWhichPart+"|"+(string)colour);

Then, in the listen event in the target furniture, 

listen(integer channel, string name, key id, string message)	{		if (llGetOwnerKey(id)!=owner){			return;		}		llSetTimerEvent(30.0);		list temp = llParseString2List(message,["|"],[]);		string component = llList2String(temp,0);		vector colour = (vector)llList2String(temp,1);		if ("cushions"==component){			//do colouring stuff to cushions		}		else if ("arms"==component){			//do colouring stuff to arms		}	}

 Alternatively, of course, you could have the furniture check which component group the touched prim belonged to, make a note of it, and then apply the selected colour to that group.   I think I would provide a way for the user explicitly to select a group, though (either via the hud or by having the furniture put up a menu) rather than rely on them touching the right prim.

Share this post


Link to post
Share on other sites

Well since I haven't really explained it yet I'll show you what I am doing with my hud and how it is currently set up.

hud.jpg

You choose what section you want to edit and then the color menu appears. After that you select your color and the furniture will change.  The furniture is mesh so instead of click a specific object it is reading which face you clicked and then telling the HUD so it can set it self up. Basically the furniture piece, when clicked, figures out what face you clicked and then activates the corresponding chair section script. That then tells which message the color swatch will send out. It seems I have this script set up a bit more confusing then it should be but it is working fine so far. I am just trying to make it even more useable now with the random channel so that the HUD can register any piece of furniture.

Also thanks for all the help, it is extremely appreciated! I'm still learning so any advice and help is a life saver.

Currently this is how my scripts work. I did not edit in your parts yet as I have been trying to get it working with no luck.

You click what part you want to edit, chair body for example:

default{    state_entry()    {        llListen(-5256, "", NULL_KEY, "");    }    touch_start(integer total_number)    {        llSay(-5256, "chairbody");        //lSay(PUBLIC_CHANNEL, "chairbody");        llSetTexture("ab847c3b-3a17-bcf7-c0bd-d39b3f551939", ALL_SIDES);    }         listen( integer channel, string name, key id, string message )    {                             if(llToLower(message) == "chairbodyselect" )                                         {                llSay(-5256, "chairbody");                llSetTexture("ab847c3b-3a17-bcf7-c0bd-d39b3f551939", ALL_SIDES);            }                          else if(llToLower(message) == "chaircushions" ||                                                 llToLower(message) == "chairlegs" ||                    llToLower(message) == "chaircushionsselect" ||                                           llToLower(message) == "chairlegsselect" ||                    llToLower(message) == "exit" )            {                llSetTexture("cb3f328b-71ac-f8c7-6b35-07c9610a9b65", ALL_SIDES);            }      }}

 

 

Then you choose a color, red for example:

string color;string colorchoice;default{    state_entry()    {         llListen(-5256, "", NULL_KEY, "");        colorchoice = "red";    }    touch_start(integer num)    {        if( color == colorchoice || color == colorchoice + "1" || color == colorchoice + "2" )        {             llSay(-5256, color);             //llSay(PUBLIC_CHANNEL, color);        }                    }        listen( integer channel, string name, key id, string message )    {                if(llToLower(message) == "exit")                {                     llSetAlpha(0.0, ALL_SIDES);                    color = " ";                }                    else if(llToLower(message) == "chairlegs")                {                     llSetAlpha(1.0, ALL_SIDES);                        color = colorchoice;                                                              }                else if(llToLower(message) == "chaircushions")                {                     llSetAlpha(1.0, ALL_SIDES);                      color = colorchoice + "1";                }                            else if(llToLower(message) == "chairbody")                {                     llSetAlpha(1.0, ALL_SIDES);                     color = colorchoice + "2";                }                   }}

 

 

Then the chair changes colors: This script also determines if you touched a face sends a message back so that the HUD will change to effecting that face. 

integer chairlegs;integer chairbody;integer chaircushions;default{    state_entry()    {        chairlegs = 2;        chairbody = 0;        chaircushions = 1;        llListen(-5256, "", NULL_KEY, "");    }        touch_start(integer num_detected)    {        integer face = llDetectedTouchFace(0);        if (face == TOUCH_INVALID_FACE)            {            llSay(0, "The surface you touched could not be determined");            }        else if (face == chairlegs )            {            llSay(-5256, "chairlegsselect" );            }        else if (face == chairbody )            {            llSay(-5256, "chairbodyselect" );            }            else if (face == chaircushions )            {            llSay(-5256, "chaircushionsselect" );            }        }        listen( integer channel, string name, key id, string message )    {                                         if (llToLower(message) == "red")            {                    llSetColor(<1.00000, 0.00000, 0.00000>,chairlegs);                               }
else if (llToLower(message) == "red1") { llSetColor(<1.00000, 0.00000, 0.00000>,chaircushions); } else if (llToLower(message) == "red2") { llSetColor(<1.00000, 0.00000, 0.00000>,chairbody); } } }

 

 

 

I added in your parts but I don't want to overfill this post with code to show scripts. I am not sure what I need to fix though as I couldn't get them working.

 

 

Share this post


Link to post
Share on other sites

The changes I would make to what I posted are (obviously you need to set up the channels and stuff, but you can what I've missed out)

In the furniture

list faces =[ // face number, name of component	0,"body",	1,"arms",	2,"legs",	4,"cushions"		];string face;integer facenumber;integer hud_channel;default{	state_entry()	{		//do set up stuff	}	touch_start(integer total_number)	{		toucher = llDetectedKey(0);		if(owner == toucher){// if my owner has touched me			llResetTime(); // zero the script time			llOwnerSay("hold the mouse key down for at least 1.5 seconds to activate the listener");			//this is for the purposes of an example.. probably you want to have the hud explain this to the owner in an real build		}	}	touch_end(integer total_number)	{		if((toucher == owner) && (llGetTime()>1.5)){ //if the mouse key was held down for more than 1.5 seconds			face = llList2String(faces, (llListFindList(faces,[llDetectedTouchFace(0)])+1));//name of face			llOwnerSay("You touched the "+face);//for debugging			llRegionSayTo(owner,hud_channel,face); //acknowledge message by sending name of touched face, thus also providing uuid			llListenRemove(handle);			handle = llListen(hud_channel,"","",""); //start listening for messages from the hud			llSetTimerEvent(30.0);		}	}	listen(integer channel, string name, key id, string message)	{		if (llGetOwnerKey(id)!=owner){			return;		}		llSetTimerEvent(30.0);		list temp = llParseString2List(message,["|"],[]);		integer n = llListFindList(faces,[llList2String(temp,0)]);//get the index number of the face		if(~n){// if it exists 			llSetColor((vector)llList2String(temp,1),llList2Integer(faces,(n-1)));			//turn the second part of the message into a vector, and then look up the face number -- the list entry immediately before the name of the face		}	}	timer()	{		llRegionSayTo(owner,hud_channel,"bye");// tell the hud I've stopped listening		llListenRemove(handle);		llSetTimerEvent(0.0);	}}

 

  and in the hud

list buttons =[	"body",	"arms",	"legs",	"cushions"		];string face;integer hud_channel;default{	state_entry()	{		//llSay(0, "Hello, Avatar!");	}	listen(integer channel, string name, key id, string message)	{		if (llGetOwnerKey(id)!=owner){			return;		}		if("bye"==message){			llOwnerSay("The "+name+" has stopped listening");			target="";			face ="";		}		else{			integer n = llListFindList(buttons,[message]);			if (~n){				target = id;				face = message;				//do whatever you need to to highlight the appropriate hud button, according to whatever the active face is			}		}	}	touch_start(integer total_number)	{		// test to make sure you've touched a colour button on the hud and then decide what colour that represents		if(target){			if (face){				llRegionSayTo(target, hud_channel,face+"|"+(string)colour);			}		}	}}

 For what it's worth, I still think it's better to use the hud to select the components you want to colour, rather than just use the colour buttons to indicate which component you've selected by touching the chair, but it's up to you.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  
Followers 0