Jump to content

My frustrating button


Todd Sivith
 Share

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

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

Recommended Posts

Hey all, I'm fairly new to scripting.  I have a little experience with XML and HTTP. I've searched all over and tried multiple different LSL script variations (and more than likely it's just because I've gone down the rabbit hole and the answer is obvious), but I'm trying to make a simple script to push a button down and have it pop back up.  It will have a whitelist and a sound as well when it's pushed. It's a linked prim #2 of 2. Here's what I have so far, I have the script inside the linked #2 prim.  The sound plays, but the button does not move. (I haven't put the whitelist ID#s in yet)

Added picture- the white part is the prim I want to move down then up after a short delay.

Thank you for your help! 

 

list gAvWhitelist = ["","",""];
 integer toggle = -1;
 integer toggle2 = -1;
 
 
 move(vector direction)
 {    
     integer p = 0;
     integer n = 10;
     for (; p < n; ++p) {
         llSetPos(llGetPos() + direction);  
     }
 }

default
{
    touch_start(integer total_number)
    {
        list Properties = llGetObjectDetails(llGetKey(),[OBJECT_CLICK_ACTION]);
        integer Click = llList2Integer(Properties,0);
        if (!Click && (~llListFindList(gAvWhitelist,[(string)llDetectedKey(0)])) )

     {
        llPlaySound(llGetInventoryName(INVENTORY_SOUND,0), 1);
     }

        {
         toggle = ~ toggle;
         if(toggle)
             llSetTimerEvent(1);
         else
             llSetTimerEvent(0);
        } 
     }
     timer()
     {        toggle2 = ~ toggle2;
 
         if(toggle2)
             move(<0,0,-0.5>);
         else
             move(<0,0,0.5>);
     }
}

Button_001.png

Edited by Todd Sivith
added picture
Link to comment
Share on other sites

There are a lot of fundamental issues which demonstrate a lack of fundamental knowledge on how the logic is supposed to work. . .

but putting that to the side for a moment, the reason it doesn't move at all is because llSetPos(llGetPos() + direction);   doesn't really work for linked prims.

fixing only that problem and leaving the rest mostly alone:

list gAvWhitelist = ["","",""];
 integer toggle = -1;
 integer toggle2 = -1;
 
 
 move(vector direction)
 {   llOwnerSay("Move! "+(string)direction);
     integer p = 0;
     integer n = 10;
     for (; p < n; ++p) {
         // this wasn't working, needs to be changed for linked prim:
        llSetLinkPrimitiveParamsFast(LINK_THIS,
        [   PRIM_POS_LOCAL,
                llList2Vector(llGetLinkPrimitiveParams(LINK_THIS,[PRIM_POS_LOCAL]),0)
                + direction
        ]);  
     }
 }

default
{
    touch_start(integer total_number)
    {   llOwnerSay("Touch!");
        // this part isn't useful:
        //list Properties = llGetObjectDetails(llGetKey(),[OBJECT_CLICK_ACTION]);
        //integer Click = llList2Integer(Properties,0);
        if ( (~llListFindList(gAvWhitelist,[(string)llDetectedKey(0)])) )
        {   llOwnerSay("Whitelist!");
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,0), 1);
        }

        //{ // remove non-functional brackets.
        toggle = ~ toggle;
        if(toggle)
        {   llSetTimerEvent(1);
        }else
        {   llSetTimerEvent(0);
        }
        //} 
     }
     timer()
     {   toggle2 = ~ toggle2;
         llOwnerSay("Timer!");
         if(toggle2)
             move(<0,0,-0.5>);
         else
             move(<0,0,0.5>);
     }
} 

 

  • Like 1
Link to comment
Share on other sites

There seem to be some other issues (I don't quite follow the idea with the touch event, and "toggle" starts in the wrong state resulting in it stopping the timer on first press, not starting it but I'll leave those for you to think about), but the reason for the button not moving is that llSetPos in a child prim uses local coordinates, i.e. in relation to the root position already. Adding llGetPos() to that will result in an attempt to move outside linkset bounds, so nothing happens.

Additionally, llGetPos has a forced 0.2 second delay which would result in very slow, choppy movement.

I'd try this instead:

 move(vector direction)
 {    
     integer p = 1; // no reason to start at 0, the object is already there
     integer n = 3; // fewer steps, let the viewer movement interpolation do the work
     for (; p < n; ++p) {
        llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POS_LOCAL, ((float)p/n)*direction]);  // scale between 1/n..1, no innate delay
        llSleep(0.05); // shorter delay
     }
 }

 

  • Like 2
Link to comment
Share on other sites

32 minutes ago, Quistess Alpha said:

llSetPos(llGetPos() + direction);   doesn't really work for linked prims.

I thought this was the case, so I looked up llSetPos() in the Wiki to see how someone could be misled by the documentation. It says:

  • Child prims (non root prims)

This would definitely lead me to think that llSetPos() could work for a child (linked) prim if I didn't know about llSetLinkPrimitiveParamsFast().

Link to comment
Share on other sites

26 minutes ago, Love Zhaoying said:

This would definitely lead me to think that llSetPos() could work for a child (linked) prim if I didn't know about llSetLinkPrimitiveParamsFast().

I was lazy and didn't read the documentation, just went off my intuition from previous experiences. llSLPPF is well, faster (but more annoying to type) than its "legacy" functions.

llSetPos(direction); should actually work in a child prim, even if it's not the "best" solution for this use-case.

Edited by Quistess Alpha
  • Thanks 1
Link to comment
Share on other sites

@Todd Sivith

 

tested this with 2 cylinder prims, seems to work ok... ( this script is in the root )

integer tog = -1;
default
{
    touch_start(integer total_number)
    {  integer link = llDetectedLinkNumber(0);
       if( link == 2 )
       {    vector prim_pos = llList2Vector(llGetLinkPrimitiveParams( link, [PRIM_POSITION]),0);           
            prim_pos = ( prim_pos - llGetPos() ) / llGetRot();  
            prim_pos.z += (0.25 * (tog = -tog) );   
            llSetLinkPrimitiveParamsFast( link, [PRIM_POSITION,prim_pos]);
            llPlaySound("4c8c3c77-de8d-bde2-b9b8-32635e0fd4a6", 1.0);
       }  
    }
}

 

Edited by Xiija
  • Like 1
Link to comment
Share on other sites

How I would approach this for debugging:

- Remove the "who touched me" test. Always execute the timer etc. when touched, until you can get the rest working.

- Add llOwnerSay() calls at various points so you know the touch, timer, move, etc. are executing. Add calls to say the toggle "values" from timer and move..

- In fact, since the stated issue is "it's not moving", just have touch call the toggle / move until you get that part working.

- Follow Quistess' advice on using llSetLinkPrimitiveParamsFast(), since we're all more familiar with using that for linked prims.

Question: Can you please verify that the script was for a rezzed object and NOT an object attached to an avatar? (Sorry if I missed it.)

  • Like 1
Link to comment
Share on other sites

  • 1 month later...
On 4/6/2023 at 2:45 AM, Quistess Alpha said:

I was lazy and didn't read the documentation, just went off my intuition from previous experiences. llSLPPF is well, faster (but more annoying to type) than its "legacy" functions.

Small(-ish) note; llSetPrimitiveParamsFast is not "faster" — it simply lacks the small built-in delay that comes along with llSetPrimitiveParams.  But that delay is there for a reason, and removing it can cause it's own problems — most often when you have several of them running in quick succession.

The way to look at it, is basically this (and I wouldn't be the slightest bit surprised if this is how it's actually implemented internally):

llSetPrimitiveParams(list params) { llSetLinkPrimitiveParams(LINK_THIS, params); }
llSetLinkPrimitiveParams(integer link, list params) { llSetLinkPrimitiveParamsFast(link, params); llSleep(0.2); }
llSetLinkPrimitiveParamsFast(integer link, list params) { …do all the magical things… }

As a general rule, try to work the delay into any animation or other stuff you have going, it lets the sim actually send out the updates rather than have them just sit around filling buffers until they overflow.  Another time to use llSPFF, is if it's pretty much immediately followed by another function that also has a delay, then doubling up on the delays can be a pain…  That said, it is reasonable to use llSPPF, followed by a shorter delay, like, just 0.1s or something, also.  Just, don't reach for llSPPF just because it's "fast", that causes as many problems as it fixes, and far too many people see the word "fast" and go "oh, that's gotta be better than not-fast, right?!?" (and over the years, I've actually heard several people expressing it very much along those lines), and that's where their thinking stops.  And then they go on to tell everyone else to do that too…  (Much the same as my other favourite rant about the ++'s.)

Also, I recently spotted another post on this here forum thingo from a bit back (by someone I can't remember, but do remember thinking they seemed like someone who probably actually would know), saying basically the same thing I have been, and I think I've seen a few others also…  (Is nice validation for something I felt I was the only person saying, for a long time.)

The bottom line; I've fixed peoples problems just by getting them to try llSPP instead, and I've seen llSPPF masking other problems people have spent hours trying to fix; one time, they'd come into the group just before I went to bed, and were still trying to fix it when I got up the next morning — and it was solved by switching to llSPP instead of llSPPF.  (I think they eventually went back to llSPPF again for some of it, but that little built in delay worked wonders on multiple fronts.)

So, rule of thumb; try to make llSPP your default, and only switch it to llSPPF when you actually need to (I personally consider it a minor failure — it helps keep my scripting honest).

Edited by Bleuhazenfurfle
Link to comment
Share on other sites

7 hours ago, Bleuhazenfurfle said:

So, rule of thumb; try to make llSPP your default, and only switch it to llSPPF when you actually need to (I personally consider it a minor failure — it helps keep my scripting honest).

Ehh my rule of thumb is the opposite. Switching from llSPPF to llSPP is of course one of the many tools in the debugging toolbox after making sure the logic is in fact correct and you know you're telling it to do the right thing but it's doing it wrong*. But on the whole I think it works well enough most of the time, and if there's something that fails because it needs a delay, I'd rather add that delay in manually (with a good comment about the issue it fixed) rather than just make things 'more delayed' by default.

* other common fixes are to reset anything relevant on changing owners; don't read textures from a no-mod object (or other prim params if you can reasonably keep track of them in the script); llSetSoundQueueing often causes more problems than it solves, Especially don't mix it with looped sounds; Don't add euler-vectors together and expect a sane result.

  • Like 2
Link to comment
Share on other sites

20 minutes ago, Love Zhaoying said:

Could the "fast" version possibly cause things to happen "out of sequence"?

Kind of like, when you receive Chat messages out of sequence?

It is possible for the viewer to receive object appearance updates out of order, but I don't think I have ever had problems caused by changes being applied to objects out of order, but I don't ever mix variants.

Something I made for a friend appeared to be making object position and rotation changes out of order, but we discovered that the changes were made to the object in the desired order.  The rendering of the object in-world, however, gave the appearance of the move and the rotate not occurring in the desired order, which, in this application, was the important part.  To resolve this, I inserted my own little delay where needed to give the viewer's object movement smoothing time to do its thing.  You see, the in-world object movement is just updating some numbers representing the position and orientation of the non-physical object.  The viewer, however, damps the translation and rotation of the visible representation of the object to visually simulate motion and inertia.  Weird, eh?

Today I might try keyframe animation, but that seems overkill for what we were making.  Oh, animesh vault doors, anyone?

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 347 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...