Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Object to Trigger Avatar Animation

Cat Mimistrobell
Pencil Head
Join date: 27 Nov 2006
Posts: 14
02-19-2008 02:50
Hi experts!

I'm sorry if this is a stupid question, but I've tried to find the answer in the forums and on the Web - even tried writing a (total noob) script which didn't even compile(!), and I'm sure there's a simple answer to this in one of your vastly superior brainboxes :)

I've created an animation, which I want to put into an object and have that object trigger the anim. Not sure yet whether I want to trigger it when 'worn' or when 'touched'.

Edit to add:
Another possible option is to have that object contain a number of animations and offer the user a choice of these. How is that done?

Just hoping someone can advise me on these options with an idiot-proof explanation. I tried copying a pose ball script into the object (which works fine if I use the pose ball for my anim instead - it'd just be more realistic to put it in the object), but when I 'wore' the object, my av sank through the floor. I just don't get it :(

Many thanks for any help you can give!
Sho Iuga
Registered User
Join date: 6 Jun 2007
Posts: 35
02-19-2008 04:03
I dont know, why your "noob" script didnt work. Maybe your script didnt ask for permissions to animate an avatar before trying to start the animation with llStartAnimation.

Anyway, here is a script that works if your object is attached or if it is touched. If you only need one of the two remove the touch_start or the attach event from the script.

CODE

string anim = "animationname"; //put animation name here

playanim()
{
llStartAnimation(anim);
}

animate( key id )
{
if( (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) && (llGetPermissionsKey() == id) )
//if we have permissions to animate play animation
{
playanim();
}
else
{
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
//we dont yet have permission to animate, so we ask for it
//this raises the run_time_permission event below
}
}

default
{

attach(key av)
{
if( NULL_KEY == av ) return; //object was detached, so do nothing
animate( av ); //else animate avatar
}

touch_start(integer total_number)
{
key av = llDetectedKey(0);
animate( av );
}

run_time_permissions(integer perm)
{
if(perm & PERMISSION_TRIGGER_ANIMATION)
{
playanim();//we have been granted permission, so we play anim
}
}

}
Cat Mimistrobell
Pencil Head
Join date: 27 Nov 2006
Posts: 14
02-19-2008 05:36
Thank you Sho! :) What a complete star :)

That works brilliantly on the 'wear' option. Just perfect!

On the 'touch' option, it animates perfectly too, but there's no visual cue to stop the animation. Would you have any advice on that?

Also, with the 'wear' option, is there some way to return the object to it's original place when you detach it, rather than having it shoot off to inventory? (If not then is it possible for the user to 'wear' a copy and leave the original in place? Even better, to make it disappear from there while 'worn' and reappear when 'detached' - or is this getting too nightmarish...?)

Would you like me to name this script after you? Or put a credit to you in the script? More than happy to do this! :)
Sho Iuga
Registered User
Join date: 6 Jun 2007
Posts: 35
02-19-2008 06:30
It is a little troublesome to give advice on scripting, when I dont know, what your object is supposed to do (except animating an avatar).

I. Stopping the animation when touched again ... possible, let the script test if the animation is already playing. If so stop it with llStopAnimation, otherwise play it.

II. detached objects always shoot into the inventory (to the best of my knowledge). The only way to prevent this is to tell the object to kill itself when it is detached (you can execute a very few lines of code before the object ends in the inventory).

III. give a copy... I would rather have an invisible prim rezzing your object from its own inventory and wait for your object to tell it, that it got detached, wereupon it rezzes the object again. But this turns into a nightmare. When your object is taken into an other sim the rezzer might not get the message.

IV. there is an other option to trigger your animation. The way it is done with most poseballs the animation triggers when an avatar sits on it. Depending on how your object shall behave that might be a better option.


The touch version with dialog to choose animation and an option to stop
CODE

list animlist = ["bow","clap","sit","stop"];
//put animation names here instead of bow clap sit, dont delete stop
integer channel = 34255; //change the number
string anim;
integer listenhandle;

playanim(key av)
{
integer index = llGetListLength(animlist);
list animsplaying = llGetAnimationList(av);
while(index--)
{
string animtest = llList2String(animlist,index);
if(llListFindList(animsplaying,[animtest]) != -1) llStopAnimation(animtest);
//stop playing anims
llStartAnimation("stand");//This line might be unnecessary
//but I had some weird results ending the animations, when I tested the script.
//the line insures the avatar will stand normally after ending the anims.
}
if(anim != "stop") llStartAnimation(anim);
}

integer reqperm( key id )
{
if( (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) && (llGetPermissionsKey() == id) )
//if we have permissions to animate play animation
{
return TRUE;
}
else
{
llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
//we dont yet have permission to animate, so we ask for it
//this raises the run_time_permission event below
return FALSE;
}
}

default
{
touch_start(integer total_number)
{
key av = llDetectedKey(0);
listenhandle = llListen(channel, "", av, "");
llDialog(av, "choose animation", animlist, channel);
}
run_time_permissions(integer perm)
{
if(perm & PERMISSION_TRIGGER_ANIMATION)
{
playanim(llGetPermissionsKey());//we have been granted permission, so we play anim
}
}
listen(integer channel, string name, key av, string message)
{
llListenRemove(listenhandle); //remove the listener to decrese server load
anim = message;
if(reqperm( av )) playanim(av);
}
}
Cat Mimistrobell
Pencil Head
Join date: 27 Nov 2006
Posts: 14
02-19-2008 08:17
That's so lovely of you, Sho. I'm sure it took more time than you really have to spare. The menu works perfectly. Thank you so much! :)

Thanks also for the time you took to explain different approaches to this. (Such genorosity and patience!) I'll plug away and see what I can do now, given your detailed comments. You never said whether you'd like a credit on the script, or in the script name. Let me know if you would.

You really know your stuff don't you?! Brilliant. :)
Sho Iuga
Registered User
Join date: 6 Jun 2007
Posts: 35
02-19-2008 09:47
too much praise Its not a difficult script. If you search around you might find a couple of simmilar scripts in the scripting library or as freebes inworld. No need for credits here.
Cat Mimistrobell
Pencil Head
Join date: 27 Nov 2006
Posts: 14
02-19-2008 10:02
It's all relative I guess ;)

You saved me many hours and a lot of pain - so it doesn't seem too much credit to me ;)

Thanks again.
Ial Yatsenko
Registered User
Join date: 11 Feb 2008
Posts: 9
02-19-2008 13:53
Another question from another noob - if my script is animating *two* avatars at once, and giving each a different animation (the owner gets animation #1, and the toucher gets animation #2), how do I tell which avatar I'm doing what to? Both llStartAnimation() and run_time_permissions() have no parameters to determine what avatar is being manipulated at a given moment, so I can't tell whether I should llStartAnimation(anim 1) or anim 2.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
02-19-2008 21:46
generally you'd animate them with different scripts, one for each av being animated. (so they'd each have seperate permissions)

however you can do it in a single script, and to be able to tell which person you are animating you would use llGetPermissionsKey which will tell you the av key that it currently has permissions for.

in your case it'd be
if (llGetPermissionsKey() == llGetOwner()){
or something similar

just be aware that with that method, the object has to ask the owner for permissions everytime, with two scripts the permissions for the owner can be stored.

if the object is sat upon it doesn't matter so much since animation permissions are automatically granted when requested (no dialog), so you could quickly grab one set of permissions, play an animation, then grab the other and repeat.
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Ial Yatsenko
Registered User
Join date: 11 Feb 2008
Posts: 9
02-20-2008 23:00
Thank you, that was VERY helpful!
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
02-24-2008 15:36
Yet another noob here...

How would I adapt the script above to give everyone permission to use the menu and choose the animation, once I'd given my initial permission to be animated?

I'm thinking as a dancer in a club, here -- there's me dancing away in a dance cage, which the customers then click to choose what dance I do for them.

I know how to do this with the MLP kit and poseballs, but I would like just to get into the cage and start dancing rather than sit on the poseball first.
Sho Iuga
Registered User
Join date: 6 Jun 2007
Posts: 35
02-24-2008 16:31
the first thing that comes up my mind is:

I first thought, just change the touch_start event to:

CODE

touch_start(integer total_number)
{
key mehasmight = llDetectedKey(0);
listenhandle = llListen(channel, "", mehasmight, "");
llDialog(mehasmight, "choose animation", animlist, channel);
}


but that is not a good idea!!! The listeners are not really taken care of, a thing to avoid for lag reasons ( actually the script wont even work after a time, as too many listeners pile up ). It would work fine if only one person at a time would use the menue and no one would leave it without choosing an option, but for your application that is unlikely. So you have to add a feature that kills old listeners.
Sorry, but we enter a rescripting of a sizeable part of the script here. And I dont feel like doing it.

Edit: Actually, not killing old llisteners is a major bug in my script design above as well :-(
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
02-24-2008 22:56
From: Innula Zenovka
Yet another noob here...

How would I adapt the script above to give everyone permission to use the menu and choose the animation, once I'd given my initial permission to be animated?

I'm thinking as a dancer in a club, here -- there's me dancing away in a dance cage, which the customers then click to choose what dance I do for them.

I know how to do this with the MLP kit and poseballs, but I would like just to get into the cage and start dancing rather than sit on the poseball first.

you need to request permissions on sit (instead of in the listen, as is done there) and then in the listen just trigger the animation for llGetPermissionsKey() (the av that it has permissions for.)
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -