Jump to content
SwireD

Piano keys script

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

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

Recommended Posts

Hello! I make a small piano of 6 keys and I need to make a script so that the buttons move slightly in space when I click on them, as if someone touched them. How to do it better? It will be a linkset. Each key separate.

I guess should start with something like:

default
{
    touch_end(integer total_number)
    {
        integer face = llDetectedTouchFace(0);
        if 
        (face == 1)
        {        
        llSay(0, "Key 1 pressed"); // Do something with key
        }
    }
}

But how to move keys? a little bit rotated and moved?

Edited by SwireD

Share this post


Link to post
Share on other sites
17 minutes ago, Fenix Eldritch said:

Better than what? What have you tried first?

Using llSetLinkPrimitiveParamsFast with the PRIM_POS_LOCAL constant and its associated parameters and targeting the clicked prim via llDetectedLinkNumber would be the typical approach.

Thank you! so i made my key move a bit up but how to make it move back in a second?

        llSetLinkPrimitiveParams(2, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(2, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, 1.0>]);

Share this post


Link to post
Share on other sites

I made this experimental draft for 3 keys but it looks not very good. How to simplify it?

default
{
    touch_end(integer total_number)
    {
        integer KEY = llDetectedLinkNumber(0);
        if 
        (KEY == 2)
        {        
        llSay(0, "Key 1 pressed");
        llSetLinkPrimitiveParams(2, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(2, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, 1.0>]);
llSleep(1);
        llSetLinkPrimitiveParams(2, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(2, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, -1.0>]);
        }
        if 
        (KEY == 3)
        {        
        llSay(0, "Key 2 pressed");
        llSetLinkPrimitiveParams(3, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(3, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, 1.0>]);
llSleep(1);
        llSetLinkPrimitiveParams(3, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(3, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, -1.0>]);
        }
        if 
        (KEY == 4)
        {        
        llSay(0, "Key 3 pressed");
        llSetLinkPrimitiveParams(4, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(4, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, 1.0>]);
llSleep(1);
        llSetLinkPrimitiveParams(4, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(4, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, -1.0>]); 
        }
    }
}

 

Edited by SwireD

Share this post


Link to post
Share on other sites

Firstly, you don't need to have all those IF statements. You already know what the currently touched key is, so use that KEY variable like this:

llSay(0, "Key "+(string)KEY+" pressed");
llSetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, 1.0>]);
llSleep(1);
llSetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, -1.0>]);
        

This will make the code flexible enough to apply the position movement to whatever key was currently pressed without needing to check through every possible key.

Secondly, you could use  llSetLinkPrimitiveParamsFast which is a variant of the function that doesn't have a built in delay on top of the explicit sleeps you have.

  • Thanks 1

Share this post


Link to post
Share on other sites
vector KEY_OFFSET_UP = < 0.0, 0.0, 0.1 >;
vector KEY_OFFSET_DN = < 0.0, 0.0, -0.1 >;
//string KEY_SOUND_1 = "";

default
{
    touch_end(integer total_number)
    {
        integer KEY = llDetectedLinkNumber(0);
    
llSay(0, "Key "+(string)KEY+" pressed");
llSetLinkPrimitiveParamsFast (KEY, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL]), 0) + KEY_OFFSET_UP]);
llSleep(0.1);
llSetLinkPrimitiveParamsFast (KEY, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL]), 0) + KEY_OFFSET_DN]);
        
    }
}
13 minutes ago, Fenix Eldritch said:

Firstly, you don't need to have all those IF statements. You already know what the currently touched key is, so use that KEY variable like this:


llSay(0, "Key "+(string)KEY+" pressed");
llSetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, 1.0>]);
llSleep(1);
llSetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL]), 0) + <0.0, 0.0, -1.0>]);
        

This will make the code flexible enough to apply the position movement to whatever key was currently pressed without needing to check through every possible key.

Secondly, you could use  llSetLinkPrimitiveParamsFast which is a variant of the function that doesn't have a built in delay on top of the explicit sleeps you have.

Thank you so much! Just one more thing - if piano has prims which dont need to move how to make this if check?

Edited by SwireD

Share this post


Link to post
Share on other sites

Ah ha... whoops. Yes that would be rather important, wouldn't it? My mistake. :)

There are a number of ways to approach this. You could use a compound IF statement that checks if KEY was equal to any of the desired linknumbers:

if (KEY == 2 || KEY == 3 || etc...)

Another way would be the give the piano keys a distinct name and check if the name of the currently pressed key was equal to that. See llGetLinkName.

if (llGetLinkName(KEY) == "pianoKey")

 

Edited by Fenix Eldritch
  • Thanks 1

Share this post


Link to post
Share on other sites
5 minutes ago, Fenix Eldritch said:

Ah ha... whoops. Yes that would be rather important, wouldn't it? My mistake. :)

There are a number of ways to approach this. You could use a compound IF statement that check of KEY was equal to any of the desired linknumbers:


if (KEY == 2 || KEY == 3 || etc...)

Another way would be the give the piano keys the a distinct name and check if the name of the currently pressed key was equal to that. See llGetLinkName for examples.

Thank you so much! Now its perfect!

vector KEY_OFFSET_DN = < 0.1, 0.0, 0.0 > ;
vector KEY_OFFSET_UP = < -0.1, 0.0, 0.0 > ;
//string KEY_SOUND_1 = "";

default {
    touch_end(integer total_number) {
        integer KEY = llDetectedLinkNumber(0);

        if (KEY == 23 || KEY == 22 || KEY == 21 || KEY == 20 || KEY == 19 || KEY == 18)

        {
            llSay(0, "Key " + (string) KEY + " pressed");
            llSetLinkPrimitiveParamsFast(KEY, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL]), 0) + KEY_OFFSET_UP]);
            llSleep(0.1);
            llSetLinkPrimitiveParamsFast(KEY, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL]), 0) + KEY_OFFSET_DN]);
        }
    }
}

 

Share this post


Link to post
Share on other sites

Now that I think more about it, you're probably going to want to have each key produce a unique sound, so it would become important to actually distinguish one key from another - whether by linknumber or name as you started to do earlier. (Apologies for leading you in circles)

Building on your latest script, you could give each piano key a unique name and then make the associated sound file have a matching name. That way when you play it, you would supply the name of the currently clicked prim as the sound's name.
 

Edited by Fenix Eldritch
  • Thanks 1

Share this post


Link to post
Share on other sites
33 minutes ago, Fenix Eldritch said:

Now that I think more about it, you're probably going to want to have each key produce a unique sound, so it would become important to actually distinguish one key from another - whether by linknumber or name.

Building on your latest script, you could give each piano key a unique name and then make the associated sound file have a matching name. That way when you play it, you would supply the name of the currently clicked prim as the sound's name.
 

From what I managed to learn from the wiki, this turned out, but for some reason it does not work. i renamed the key...

 

vector KEY_OFFSET_DN = < 0.1, 0.0, 0.0 > ;
vector KEY_OFFSET_UP = < -0.1, 0.0, 0.0 > ;
string KEY_SOUND_1 = "72a7fa0d-0e74-ca84-3894-c4eae665fac7";
string KEY_SOUND_2 = "d302a5fa-21ae-6f55-0d1c-ec55bd58f895";
string KEY_SOUND_3 = "7d5ef849-1f02-8399-3bb2-758833d455a1";
string KEY_SOUND_4 = "8b76dbc1-c003-2fe7-0f2c-6c03238e0793";
string KEY_SOUND_5 = "c9ee84ab-3ec3-ab47-9584-4bb859c2ec20";
string KEY_SOUND_6 = "502d772c-47cc-918c-40aa-0d7df0a67e11";

string KEY1;
string KEY2;
string KEY3;
string KEY4;
string KEY5;
string KEY6;

default {
    touch_end(integer total_number) {


        integer i = llGetNumberOfPrims();

        if (llGetLinkName(i) == KEY1)
        {
            llSay(0, "Key1");
        }                
        
    }
}

 

Share this post


Link to post
Share on other sites

Oh i forgot quotes! ""

But for some reason it says "Key1" for each key. And for non-key objects...

integer i = llGetNumberOfPrims();

        if (llGetLinkName(i) == "KEY1")
        {
            llSay(0, "Key1");
        }
        if (llGetLinkName(i) == "KEY2")
        {
            llSay(0, "Key2");
        }
        if (llGetLinkName(i) == "KEY3")
        {
            llSay(0, "Key3");
        }
        if (llGetLinkName(i) == "KEY4")
        {
            llSay(0, "Key4");
        }
        if (llGetLinkName(i) == "KEY5")
        {
            llSay(0, "Key5");
        }
        if (llGetLinkName(i) == "KEY6")
        {
            llSay(0, "Key6");
        }

Edited by SwireD

Share this post


Link to post
Share on other sites

llGetNumberOfPrims only returns the total number of prims in the linkset. That's not going to be very helpful here. For example, if you have ten prims in your linkset, that function will return the integer 10 every time. You were on the right track with using the KEY = llDetectedLinkNumber(0).

Try taking your previous example and modifying the llSay to look like this:

llSay(0, "linknumber " + (string) KEY + " pressed, and it's name is "+llGetLinkName(KEY));

The above code (when placed inside a touch event) will tell you the linknumber and the name of the prim touched.

Now my previous suggestion depends upon placing copies of the sound assets directly into the piano's inventory. This is because we can rename them to match their associated piano key names. The LSL functions that actually emit sounds allow you to specify a sound either by UUID, or by the name of the sound file (as long as it exists in the object's personal inventory). So the idea here is to make a given key and its associated sound have the same name. For example, find the prim with linknumber 2 and in the build tool, rename the child prim to "KEY2". Then, get the sound asset you want for that key, place it in the piano (wherever the script will reside) and rename the sound file there to be "KEY2" as well.

By doing this, we can eliminate the need for all those IF checks. Instead of checking "if key 2 is pressed, play this uuid" we can instead simply say:

llPlaysound(llGetLinkName(KEY),1.0);

The trick here is that since the specific key and associated sound have the exact same name, we don't need to do any tests. We just feed the prim's name into the sound function directly.

Try adding that to your previous example.

 

  • Thanks 1

Share this post


Link to post
Share on other sites
19 hours ago, Fenix Eldritch said:

llGetNumberOfPrims only returns the total number of prims in the linkset. That's not going to be very helpful here. For example, if you have ten prims in your linkset, that function will return the integer 10 every time. You were on the right track with using the KEY = llDetectedLinkNumber(0).

Try taking your previous example and modifying the llSay to look like this:


llSay(0, "linknumber " + (string) KEY + " pressed, and it's name is "+llGetLinkName(KEY));

The above code (when placed inside a touch event) will tell you the linknumber and the name of the prim touched.

Now my previous suggestion depends upon placing copies of the sound assets directly into the piano's inventory. This is because we can rename them to match their associated piano key names. The LSL functions that actually emit sounds allow you to specify a sound either by UUID, or by the name of the sound file (as long as it exists in the object's personal inventory). So the idea here is to make a given key and its associated sound have the same name. For example, find the prim with linknumber 2 and in the build tool, rename the child prim to "KEY2". Then, get the sound asset you want for that key, place it in the piano (wherever the script will reside) and rename the sound file there to be "KEY2" as well.

By doing this, we can eliminate the need for all those IF checks. Instead of checking "if key 2 is pressed, play this uuid" we can instead simply say:


llPlaysound(llGetLinkName(KEY),1.0);

The trick here is that since the specific key and associated sound have the exact same name, we don't need to do any tests. We just feed the prim's name into the sound function directly.

Try adding that to your previous example.

 

Thank you so VERY MUCH! Now it is finally perfect!

vector KEY_OFFSET_DN = < 0.1, 0.0, 0.0 > ;
vector KEY_OFFSET_UP = < -0.1, 0.0, 0.0 > ;

default {
    touch_end(integer total_number) {
        integer KEY = llDetectedLinkNumber(0);

        if (KEY == 23 || KEY == 22 || KEY == 21 || KEY == 20 || KEY == 19 || KEY == 18) {
            llPlaySound(llGetLinkName(KEY), 1.0);
//            llSay(0, "linknumber " + (string) KEY + " pressed, and it's name is " + llGetLinkName(KEY));
            llSetLinkPrimitiveParamsFast(KEY, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL]), 0) + KEY_OFFSET_UP]);
            llSleep(0.1);
            llSetLinkPrimitiveParamsFast(KEY, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(KEY, [PRIM_POS_LOCAL]), 0) + KEY_OFFSET_DN]);
        }
    }
}

 

Share this post


Link to post
Share on other sites
You are about to reply to a thread that has been inactive for 277 days.

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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...