Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Synchronizing Animations

Eta Carver
Registered User
Join date: 9 Feb 2008
Posts: 6
02-09-2008 10:47
I'm looking for some script code to launch animations when both dance balls are occupied. Exactly like all the couples animations and dances around. Just started scripting so seeing a worked example would be fantastic help.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
02-09-2008 12:57
I can't help with a working example, but I know the general way they are made.

each poseball triggers an immediate static animation (just the first 2 frames of whole thing), then when the second av sits, a message is sent causing both full animations to play.

it can be done in one script, but is easier in two,

script a behavior:
when an av sits or unsits it sends a message to script b
if an av sits, it starts a static pose
if it recieves a go message from script b it goes
if it recieves a stop message (and there's still an av) it stops and reverts to the static pose

script b behavior:
plays a static pose when av sits
if two avs are present it sends the start message
if an av leaves, it sends the stop message (reverting to the static pose if it still has an av)

for best simultaneity script b should hear and respond to it's own start/stop messages the same way script a does, optionally you can add a listen when an av sits, that triggers a stop and a play message, in case the avs get out of synch on one of the viewrs
_____________________
|
| . "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...
| -
Vang Foden
Registered User
Join date: 10 Feb 2008
Posts: 10
Is there a scripting guru out there?
02-10-2008 13:32
Thanks Void for the method:)

I was very kindly donated the following which as I understand it, is along the lines of the method Void was advocating. MY scripting is far too weak to be absolutely certain:(

There appear to be two repeatable scenarios where the script does not properly clear the animation.

BUG 1
The female animation is not cleared if she unsits first.

BUG2
The male animates and stops correctly however if he animates again he is incorrectly positioned with the animation playing in a default sit position not the true animation position.

I'll post both the Male and Female Scripts below in the hope some bright spark can help us out.

Here's to Hope!!

MALE
//First value is the waiting animation, second and else is for motion. The order is respected!
//Example: list animation = ["wait", "motion1", "motion2", "motionN"];
list ANIMS = ["animW", "animA", "animB", "animC"];

string BUTTON = "Play"; // text of the pie menu
string TITLE = "mal"; // floating text
float TIMEOUT = 30.0; // time to play each anim listed
vector ROTATION = <0,0,0>; // euler in degrees (like the edit box)
vector OFFSET = <0,0,0.5>; // how far the person sits from the ball. ( <X,Y,Z> )

//do not edit after this line if you are not confortable with programmin languages

string BALL = "MAL"; integer RUN = TRUE; integer MAL; integer FEM; integer INDEX;

show() { RUN = TRUE; llSetText(TITLE, <1.0,1.0,1.0> ,1.0); llSetAlpha(1.0, ALL_SIDES); }

hide() { RUN = FALSE; llSetText("", ZERO_VECTOR, FALSE); llSetAlpha(0.0, ALL_SIDES); }

stopAnims() {
integer i; list anims = llGetAnimationList(llGetPermissionsKey());
for (i=0;i<llGetListLength(anims);++i) llStopAnimation(llList2Key(anims, i));
}

default {
state_entry() {
llSitTarget(OFFSET, llEuler2Rot(ROTATION * DEG_TO_RAD));
if (llAvatarOnSitTarget()) { llUnSit(llAvatarOnSitTarget()); }
llSetSitText(BUTTON); if (RUN) show(); else hide(); MAL = FALSE; FEM = FALSE;
}

link_message(integer sender_num, integer num, string str, key id) {
if ((string)id=="BALL";) {
if (str=="MAL";) { MAL=num; } else if (str=="FEM";) { FEM=num; }
if (FEM && MAL) { llMessageLinked(LINK_SET, TRUE, "ANIMS", NULL_KEY); }
else if (FEM || MAL) { llMessageLinked(LINK_SET, FALSE, "ANIMS", NULL_KEY); }
else { llResetScript(); }
}
else if (str=="ANIMS";) {
if (num) { INDEX = 0; llSetTimerEvent(0.01); }
else { llSetTimerEvent(0.0); if (llAvatarOnSitTarget()) { stopAnims(); llStartAnimation(llList2String(ANIMS,0)); } }
}
}

timer() { if (++INDEX==llGetListLength(ANIMS)) { INDEX=TRUE; } llStartAnimation(llList2String(ANIMS,INDEX)); llSetTimerEvent(TIMEOUT); }

changed(integer change) {
if(change & CHANGED_LINK) { key avatar = llAvatarOnSitTarget();
if (avatar!=NULL_KEY) {
if(llGetPermissionsKey() != avatar) { llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION); }
hide(); llMessageLinked(LINK_SET, TRUE, BALL, (key)"BALL";);
}
else if ((llGetPermissionsKey()!=NULL_KEY) && (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)) {
show(); llMessageLinked(LINK_SET, FALSE, BALL, (key)"BALL";); stopAnims();
} } if (change & CHANGED_INVENTORY) { llResetScript(); } }

run_time_permissions(integer perm) {
key avatar = llAvatarOnSitTarget();
if(perm & PERMISSION_TRIGGER_ANIMATION && llKey2Name(avatar) != "" && avatar == llGetPermissionsKey()) {
stopAnims();
llStartAnimation(llList2String(ANIMS,0));
hide();
} } }


And FEMALE

//First value is the waiting animation, second and else is for motion. The order is respected!
//Example: list animation = ["wait", "motion1", "motion2", "motionN"];
list ANIMS = ["animW", "animA", "animB", "animC"];

string BUTTON = "Play"; // text of the pie menu
string TITLE = "fem"; // floating text
float TIMEOUT = 30.0; // time to play each anim listed
vector ROTATION = <0,0,0>; // euler in degrees (like the edit box)
vector OFFSET = <0,0,0.5>; // how far the person sits from the ball. ( <X,Y,Z> )

//do not edit after this line if you are not confortable with programmin languages

string BALL = "FEM"; integer RUN = TRUE; integer MAL; integer FEM; integer INDEX;

show() { RUN = TRUE; llSetText(TITLE, <1.0,1.0,1.0> ,1.0); llSetAlpha(1.0, ALL_SIDES); }

hide() { RUN = FALSE; llSetText("", ZERO_VECTOR, FALSE); llSetAlpha(0.0, ALL_SIDES); }

stopAnims() {
integer i; list anims = llGetAnimationList(llGetPermissionsKey());
for (i=0;i<llGetListLength(anims);++i) llStopAnimation(llList2Key(anims, i));
}

default {
state_entry() {
llSitTarget(OFFSET, llEuler2Rot(ROTATION * DEG_TO_RAD));
if (llAvatarOnSitTarget()) { llUnSit(llAvatarOnSitTarget()); }
llSetSitText(BUTTON); if (RUN) show(); else hide(); MAL = FALSE; FEM = FALSE;
}

link_message(integer sender_num, integer num, string str, key id) {
if ((string)id=="BALL";) {
if (str=="MAL";) { MAL=num; } else if (str=="FEM";) { FEM=num; }
if (FEM && MAL) { llMessageLinked(LINK_SET, TRUE, "ANIMS", NULL_KEY); }
else if (FEM || MAL) { llMessageLinked(LINK_SET, FALSE, "ANIMS", NULL_KEY); }
else { llResetScript(); }
}
else if (str=="ANIMS";) {
if (num) { INDEX = 0; llSetTimerEvent(0.01); }
else { llSetTimerEvent(0.0); if (llAvatarOnSitTarget()) { stopAnims(); llStartAnimation(llList2String(ANIMS,0)); } }
}
}

timer() { if (++INDEX==llGetListLength(ANIMS)) { INDEX=TRUE; } llStartAnimation(llList2String(ANIMS,INDEX)); llSetTimerEvent(TIMEOUT); }

changed(integer change) {
if(change & CHANGED_LINK) { key avatar = llAvatarOnSitTarget();
if (avatar!=NULL_KEY) {
if(llGetPermissionsKey() != avatar) { llRequestPermissions(avatar, PERMISSION_TRIGGER_ANIMATION); }
hide(); llMessageLinked(LINK_SET, TRUE, BALL, (key)"BALL";);
}
else if ((llGetPermissionsKey()!=NULL_KEY) && (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)) {
show(); llMessageLinked(LINK_SET, FALSE, BALL, (key)"BALL";); stopAnims();
} } if (change & CHANGED_INVENTORY) { llResetScript(); } }

run_time_permissions(integer perm) {
key avatar = llAvatarOnSitTarget();
if(perm & PERMISSION_TRIGGER_ANIMATION && llKey2Name(avatar) != "" && avatar == llGetPermissionsKey()) {
stopAnims();
llStartAnimation(llList2String(ANIMS,0));
hide();
} } }