Jump to content

Play random animation on touch script


Galatheus
 Share

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

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

Recommended Posts

Assuming that you have all the rest of your script figured out, the touch_start event should look something like this:

touch_start(integer num)
{
    integer i = llGetInventoryNumber(INVENTORY_ANIMATION);
    integer iThisAnimation = (integer)llFrand((float)i));
    if ( llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)
    {
        llStopAnimation( strCurrentAnimation );
        strCurrentAnimation = llGetInventoryName(INVENTORY_ANIMATION, iThisAnimation);
        llStartAnimation( strCurrentAnimation );
    }
}

Remember to make strCurrentAnimation a global string constant so that it persists from one time that you enter the touch_start event to the next, and give it an initial value in your run_time_permissions event. You can make this fancier, of course, and you can also streamline it to make it cleaner, but that's the idea.  Do remember, of course, to request PERMISSION_TRIGGER_ANIMATION early in your script.  Consult the LSL wiki if you don't know how to do that.

Edited by Rolig Loon
Cleaner wording
  • Like 2
Link to comment
Share on other sites

thank you for the response. I'm really new to scripting. I started a week ago. So please cut me some slack if my questions are gonna be basic.

For long term of course I want to learn to script on my own from scratch. And for this particular script I can't seem to lead myself to the right direction. Which tutorials to watch for this specific topic, and what not. So if you guys know the best tutorials I would appreciate their links.

Now, I get syntax errors whenever I try to solve this. Of course I know this isn't the full script. I just don't know how to set the timer, run time and state entry events to make this touch event function work. As for the short term solution, I don't exactly know what to write to make the strCurrentAnimation a global string and what purpose. Is it to set what animations are gonna be used?

default
{
    state_entry()
    {
        llOwnerSay( "Your HUD is ready" );
        llOwnerSay( "Visit.." );
    }
    touch_start(integer detected)
    {
        llTriggerSound(llGetInventoryName(INVENTORY_SOUND,0), 1);
        llRequestPermissions(llDetectedKey(0), PERMISSION_TRIGGER_ANIMATION);
    }
    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            llStartAnimation("2");
            llSetTimerEvent(5.0);
        }
    }
    timer()
    {
        llSetTimerEvent(0.0);
        llStopAnimation("2");
    }
}

this is what I have so far.

Edited by Galatheus
Added codes
Link to comment
Share on other sites

2 hours ago, Galatheus said:

I don't exactly know what to write to make the strCurrentAnimation a global string and what purpose. Is it to set what animations are gonna be used?

Right, if you look at Rolig's sample code, you'll see that the script is using that variable to keep track of which animation is playing in order to remember which animation to stop the next time the object is touched, before playing the next randomly selected animation.

The strCurrentAnimation variable needs to be in the global scope because it needs to keep its value across multiple event occurrences (multiple touches in this case), and the way to tell the compiler that a variable is global is to declare it before the default state is defined. So here you'd just put a line at the top of the script that looks something like

string strCurrentAnimation;

(irrelevant tangent: LSL is kinda weird in that there's no state-wide scope, only script global or block local. This won't mean much until you need multiple states, but what I mean is, other languages would permit variables to be declared just inside the state block -- like right after "default" -- shared across all the event handlers within that state only. Instead they must be declared globally, before even the default state, and shared across the whole program. One reason might be that LSL states aren't all that common -- and should probably be even less common than they are.)

[ETA: I think you'll get a runtime error if you merely declare that variable and then try to stop that animation, which will start out as the empty string (""). Instead, you might initialize it when declared, perhaps to some unlikely built-in animation, a la 

string strCurrentAnimation = "backflip";

because there's no fussing about stopping an animation that's not playing. Or you could test whether that variable has a non-empty value before calling llStopAnimation() on it. Or you could assign it a value somewhere else, perhaps in state_entry. Or... well, you get the idea. Also, depending what the animations are that you'll be playing, you may also want to stop other animations the avatar is currently playing that might conflict with the new ones, but that's all for later.]

Edited by Qie Niangao
  • Like 2
Link to comment
Share on other sites

Qie has explained it quite nicely.  There are really two things going on in that touch_start example I posted for you.  One is the business of stopping whatever animation is already playing.  To do that, you need to know which anim that is, by name. That's why I introduced the strCurrentAnimation variable as a place to hold that information. As Qie explained, we have to make strCurrentAnimation a global variable because the information would otherwise be lost as soon as the flow of execution leaves the touch_start event. Think of a global variable as a sort of bucket into which you store information for later use -- in this case, for the next time you click to enter the touch_start event.

The other thing that's going on is choosing and then starting a new value for strCurrentAnimation. That's where you need the llFrand() function, which you should study in the LSL wiki. We want to choose a random one of the available animations in your object's inventory. So, first we count how many there are with the integer variable i.  The llFrand() function requires a float variable to act on, so we have to temporarily convert i to a float:

llFrand( (float) i)

This operation is called typecasting.  Now, llFrand may need a float to operate on, but we want it to return an integer, because we will need it to identify which animation to use next. Therefore, we need to typecast its result back again:

integer iThisAnimation = (integer)llFrand((float)i));

and then use that value to pick the next strCurrentAnimation:

strCurrentAnimation = llGetInventoryName(INVENTORY_ANIMATION, iThisAnimation);

Once you learn to follow this sort of logic, you will be able to compress the sort of code that I wrote into a much tighter version.  I would normally do that myself, but I gave you that expanded version so that it would be easier to understand.

  • Like 1
Link to comment
Share on other sites

Thank you for your answers, it helped a lot. I am now figuring out little by little certain codes and how to properly use them. Also thanks to the LSL Portal, with all you guys' help I'm able to make the script work.  I still have a long way to go to completely understand LSL codes but yeah thank you!

  • Like 1
Link to comment
Share on other sites

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