Jump to content

detect prim names


Tattooshop
 Share

You are about to reply to a thread that has been inactive for 1513 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hello! how to make this script work not from the prim numbers but from the names of the buttons in the hud? (it plays different animations)

StopAnims()
{
    llStopAnimation("anim1");
    llStopAnimation("anim2");
    llStopAnimation("anim3");
}

default
{
    state_entry()
    {
        llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
    }

    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            StopAnims();
        }
    }

    changed(integer change)
    {
        if (change & CHANGED_OWNER)
        {
            llResetScript();
        }
    }

    touch_start(integer num)
    {
        integer button = llDetectedLinkNumber(0);
        {
            if (button == 5)
            {
                StopAnims();
                llStartAnimation("anim1");
            }

            if (button == 4)
            {
                StopAnims();
                llStartAnimation("anim2");
            }

            if (button == 3)
            {
                StopAnims();
                llStartAnimation("anim3");
            }

            if (button == 2)
            {
                StopAnims();
            }
        }
    }
}

I tried this but it doesn’t work.

string button1;
string button2;
string button3;
string stop;

StopAnims()

{
    llStopAnimation("anim1");
    llStopAnimation("anim2");
    llStopAnimation("anim3");
}


default
{
    state_entry()
    {
        llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
    }

    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            StopAnims();
        }
    }

    changed(integer change)

    {
        if (change & CHANGED_OWNER)
        {
            llResetScript();
        }
    }

    touch_start(integer num)
    {
        integer i = llGetNumberOfPrims();
        for (; i >= 0; --i)
        {
            if (llGetLinkName(i) == button1)
            {
                StopAnims();
                llStartAnimation("anim1");
            }

            if (llGetLinkName(i) == button2)
            {
                StopAnims();
                llStartAnimation("anim2");
            }

            if (llGetLinkName(i) == button3)
            {
                StopAnims();
                llStartAnimation("anim3");
            }

            if (llGetLinkName(i) == stop)
            {
                StopAnims();
            }
        }
    }
}

 

Link to comment
Share on other sites

11 minutes ago, Rolig Loon said:

Your solution would work if you had assigned values to the variables button1, button2, button3, and stop.  As it is. the variables exist but their values are all " ".  And, of course, you have to actually name the button prims with those values.

Thank you! So i added

integer button1 = 5;
integer button2 = 4;
integer button3 = 3;
integer stop = 2;

but it says Type mismatch error. Something I am doing wrong.

But is it possible to do it without prim numbers at all?

Link to comment
Share on other sites

2, 3, 4, and 5 are integers. Your prim's names are strings.  If you really want to use numerals as the prim names, then assign their string values to the string variables button1, button2, button3, and stop.

string button1 = "5";

string button2 = "4";

string button3 = "3";

string stop = "2";

  • Thanks 1
Link to comment
Share on other sites

At the top of your second script, you defined the string variables as button1, button2, etc. but those are just the names of the variables. You still need to give those variables a value. If the names of the child prims are "button1", "button2", etc, then you need to assign that to the string variables. For example:

string button1 = "button1";	//the variable identified as button1 contains the value "buton1"

 

  • Thanks 1
Link to comment
Share on other sites

Even after you get your variables cleared up, there is still a lingering flaw in your second script that will cause undesirable behavior (as I understand it).

In your touch_start event, you are going to loop over every prim in the hud's linkset. On each iteration of the loop, your script will perform a series of checks to see what the name of the current child pim is... and then stop all animations and start the one that corresponds to a given name. Do you see the problem here?

You aren't checking what link number was clicked. Your loop is going to inspect EVERY prim in the linkset, so all of those IF tests will eventually pass. Even the "stop" one. Depending on the order of your links, one of those bits of code is always going to be the last one executed, no matter what.

Edited by Fenix Eldritch
  • Thanks 1
Link to comment
Share on other sites

8 minutes ago, Fenix Eldritch said:

Even after you get your variables cleared up, there is still a lingering flaw in your second script that will cause undesirable behavior (as I understand it).

In your touch_start event, you are going to loop over every prim in the hud's linkset. On each iteration of the loop, your script will perform a series of checks to see what the name of the current child pim is... and then stop all animations and start the one that corresponds to a given name. Do you see the problem here?

You aren't checking what link number was clicked. Your loop is going to inspect EVERY prim in the linkset, so all of those IF tests will eventually pass. Even the "stop" one. Depending on the order of your links, one of those bits of code is always going to be the last one executed, no matter what.

Yes, I just wanted to write about it. avatar reacts strangely to button presses. I added   llSay(0, "Touched1")   for the test and this is what comes out when any button is pressed

[07:18] Object: Touched1
[07:18] Object: Touched2
[07:18] Object: Touched3

string button1 = "button1";
string button2 = "button2";
string button3 = "button3";
string stop = "stop";

StopAnims()
{
    llStopAnimation("anim1");
    llStopAnimation("anim2");
    llStopAnimation("anim3");
}

default
{
    state_entry()
    {
        llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
    }

    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            StopAnims();
        }
    }

    changed(integer change)
    {
        if (change & CHANGED_OWNER)
        {
            llResetScript();
        }
    }

    touch_start(integer num)
    {
        integer i = llGetNumberOfPrims();
        for (; i >= 0; --i)
        {
            if (llGetLinkName(i) == button1)
            {
                StopAnims();
                llStartAnimation("anim1");
                        llSay(0, "Touched1");
            }

            if (llGetLinkName(i) == button2)
            {
                StopAnims();
                llStartAnimation("anim2");
                        llSay(0, "Touched2");
            }

            if (llGetLinkName(i) == button3)
            {
                StopAnims();
                llStartAnimation("anim3");
                        llSay(0, "Touched3");
            }

            if (llGetLinkName(i) == stop)
            {
                StopAnims();
            }
        }
    }
}

 

Edited by Tattooshop
Link to comment
Share on other sites

That is a for loop. It is a method of making a block of code repeat itself, to iterate over a range of values. As I mentioned above, your code as written in the second script is going to blindly loop with no regard to what button was actually clicked. It's inspecting every prim in the linkset and doing those IF tests on each prim. Which means it's going to do everything instead of just acting on a specific button's code.

I suggest you revisit your first script, as it is a simple matter to convert it to use link names instead of pure link numbers. You would essentially follow the exact same logic. No need for a loop.

In the touch_start event, change the button variable to a string instead of an integer. This will be the variable to contain the name of whatever child prim was clicked and then we will do the same IF checks, without a loop, and updated to work with your specified names. You would use a combination of llGetLinkName and feed it the return value of llDetectedLinkNumber(0). This essentially is saying "get the name of the link that was just clicked".

This would be the template:

string button = llGetLinkName(llDetectedLinkNumber(0));

if (button == "button1")
{
  //do stuff for button1
}

 

Edited by Fenix Eldritch
typos
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I don't want to beat a dead horse, but to be sure that I have been clear ......

Think of your computer's physical innards as a warehouse full of empty shelves. Your script's job is to put labeled boxes (variables) on those shelves, put specific items (values) in the boxes, and then manipulate those values (move them around from box to box, compare them to each other or to things outside the warehouse ...).  At the top of your script, you are creating the boxes and telling the computer what type of things you will be putting in them:

string button1;    // a box labeled button1 will contain items of type string.

Then you will put something in each of the boxes:

button1 = "button1";    // The box labeled button1 now has the string "button1" in it.

(You can combine those first two steps as string button1 = "button1"; )

And then your script will later ask "Does the physical thing that I have just touched have a name (a value) that is the same as the value that I put into the box labeled button1?"

if (  llGetLinkName( llDetectedLinkNumber(0) ) == button1)
{
    // do something
}

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

26 minutes ago, Fenix Eldritch said:

In the touch_start event, change the button variable to a string instead of an integer. This will be the variable to contain the name of whatever child prim was clicked and then we will do the same IF checks, without a loop, and updated to work with your specified names. You would use a combination of llGetLinkName and feed it the return value of llDetectedLinkNumber(0). This essentially is saying "get the name of the link that was just clicked".

This would be the template:


string button = llGetLinkName(llDetectedLinkNumber(0));

if (button == "button1")
{
  //do stuff for button1
}

 

 

26 minutes ago, Rolig Loon said:

(You can combine those first two steps as string button1 = "button1"; )

And then your script will later ask "Does the physical thing that I have just touched have a name (a value) that is the same as the value that I put into the box labeled button1?"


if (  llGetLinkName( llDetectedLinkNumber(0) ) == button1)
{
    // do something
}

 

Thank you both a lot! I now have two wonderful working script versions! :)❤️

 

StopAnims()
{
    llStopAnimation("anim1");
    llStopAnimation("anim2");
    llStopAnimation("anim3");
}

default
{
    state_entry()
    {
        llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
    }

    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            StopAnims();
        }
    }

    changed(integer change)

    {
        if (change & CHANGED_OWNER)
        {
            llResetScript();
        }
    }

    touch_start(integer num)
    {
        string button = llGetLinkName(llDetectedLinkNumber(0));
        {
            if (button == "button1") 
            {
                StopAnims();
                llStartAnimation("anim1");
            }

            if (button == "button2") 
            {
                StopAnims();
                llStartAnimation("anim2");
            }
            
            if (button == "button3") 
            {
                StopAnims();
                llStartAnimation("anim3");
            }         
            
            if (button == "stop")
            {
                StopAnims();
            }
        }
    }
}
string button1 = "button1";
string button2 = "button2";
string button3 = "button3";
string stop = "stop";

StopAnims()
{
    // list of your animations:
    llStopAnimation("anim1");
    llStopAnimation("anim2");
    llStopAnimation("anim3");
}

default
{
    state_entry()
    {
        llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
    }

    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            StopAnims();
        }
    }

    changed(integer change)
    {
        if (change & CHANGED_OWNER)
        {
            llResetScript();
        }
    }

    touch_start(integer num)
    {
        {
            if (llGetLinkName(llDetectedLinkNumber(0)) == button1)
            {
                StopAnims();
                llStartAnimation("anim1");
            }

            if (llGetLinkName(llDetectedLinkNumber(0)) == button2)
            {
                StopAnims();
                llStartAnimation("anim2");
            }

            if (llGetLinkName(llDetectedLinkNumber(0)) == button3)
            {
                StopAnims();
                llStartAnimation("anim3");
            }          

            if (llGetLinkName(llDetectedLinkNumber(0)) == stop)
            {
                StopAnims();
            }
        }
    }
}

 

Link to comment
Share on other sites

As a further refinement, consider creating two global lists:

list lButtonNames = ["button1", "button2", "button3", "stop"];

list lAnims = ["anim1", "anim2", "anim3"];

and then rewriting the touch_start event as

touch_start(integer num)
{
     integer idx = llListFindList( lButtonNames, [ llGetLinkName( llDetectedLinkNumber(0) ) ]);
     if ( ~idx )    // that is, "if idx is a non-negative integer ..."
    {
        StopAnims();    // Stop anims regardless of which valid button you clicked
        if (idx < 3 )   // that is, "if idx is 0, 1, or 2 ..."
        {
            llStartAnimation( llList2String( lAnims, idx ) );
        }
    }
}

That's quite a bit more compact, so it saves having to write and execute all of those separate if tests.  Aside from making your script more elegant -- always a plus -- the real benefit is that  it helps you focus on the logic of what you are trying to accomplish.  After all, scripting is above all else an exercise in logic.  Writing the touch_start event in terms of list management helps you see that this is basically an exercise in identifying whether you have touched a button that has one of a small number of predetermined names. If the button name matches one of the names in your lButtonNames list, then you not only know that it was a valid touch but you also know exactly which anim to start from lAnims, because idx refers to the same index in both lists.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

list lButtonNames = ["button1", "button2", "button3", "stop"];

list lAnims = ["anim1", "anim2", "anim3"];

StopAnims()
{
    // list of your animations:
    llStopAnimation("anim1");
    llStopAnimation("anim2");
    llStopAnimation("anim3");
}

default
{
    state_entry()
    {
        llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
    }

    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            StopAnims();
        }
    }

    changed(integer change)
    {
        if (change & CHANGED_OWNER)
        {
            llResetScript();
        }
    }

    touch_start(integer num)
    {
        integer idx = llListFindList(lButtonNames, [llGetLinkName(llDetectedLinkNumber(0))]);
        if (~idx) // that is, "if idx is a non-negative integer ..."
        {
            StopAnims(); // Stop anims regardless of which valid button you clicked
            if (idx < 3) // that is, "if idx is 0, 1, or 2 ..."
            {
                llStartAnimation(llList2String(lAnims, idx));
            }
        }
    }
}

:)

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1513 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...