POSE BALL DE COUPLE
Préambule
Avant de commencer à lire ce tutorial, vous devez absolument avoir assimilé et compris le système de fonctionnement d'une pose ball simple. Si ce n'est pas le cas, un tuto est à votre disposition sur le site web.
Script de base
Nous allons nous servir du script de base le plus épuré possible pour faire une pose ball et le modifier au fur et à mesure de ce tuto. La plus part du temps on ne donnera que des bouts de codes correspondant aux événements ayant été changés. Par rapport au script vu dans le tuto précédent nous avons rajouté une ligne qui utilise llGetInventoryName. Cela nous permet d'obtenir le nom de l'animation qui se trouve dans la pose ball et ainsi notre animation marchera indépendamment du nom de celle-ci.
string anim; default { state_entry() { //stock le nom de l'animation qui se trouve dans l'inventaire de la pose ball anim=llGetInventoryName(INVENTORY_ANIMATION, 0); llSitTarget(<0.0,0.0,0.01>, ZERO_ROTATION); } changed(integer change) { key av=llAvatarOnSitTarget(); if(av!=NULL_KEY) { llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION); } } run_time_permissions(integer perm) { llStopAnimation("sit"); llStartAnimation(anim); } }
|
Le principe
Le principe fondamental d'une pose ball de couple réside sur la synchronisation des animations. Pour une synchronisation d'un point de vu général, il faut communication !
Prenons un exemple RL simple, imaginons que vous souhaitiez sortir sur le palier en même temps que votre voisin, vous aller convenir d'une communication et de l'action à effectuer.
"Quand tu m'entends crier tu sors et je fais pareil !"
Donc nos deux poses ball liées et vont communiquer entre elle. Pour la communication, il faut que un crie pour cela on utilise la fonction llMessageLinked et pour écouter ce cri cela se traduit par l'événement link_message
On met ces deux aspects dans le même script car .
changed(integer change) { key av=llAvatarOnSitTarget(); if(av!=NULL_KEY) { llMessageLinked(LINK_ALL_OTHERS, TRUE, "", NULL_KEY); llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION); } } link_message(integer sender_num, integer num, string str, key id) { llStartAnimation(anim); } |
Les différent cas
Le premier problème c'est que si je m'assois sur la pose ball et que l'autre avatar n'est pas encore là, la pose ball va vouloir animer un avatar qui n'existe pas !
Pour résoudre ca, il suffit juste de vérifier que lorsque la pose ball reçoit un message que l'avatar est bien assis dessus grâce à la fonction que l'on a déjà vu llAvatarOnSitTarget.
| link_message(integer sender_num, integer num, string str, key id) { if(llAvatarOnSitTarget()!=NULL_KEY)llStartAnimation(anim); } |
Le deuxième problème c'est que si l'autre avatar n'est pas là, he bien je vais lancer l'animation pour rien. Comme toujours il faut le tester, et comment? en verifiant qu'il nous a deja envoyer un message. Nou allons créer une variable globale du nom de ready cette variable stockera si oui ou non j'ai reçu un message. Pensez à initialiser la variable à TRUE
link_message(integer sender_num, integer num, string str, key id) { ready=num; if(llAvatarOnSitTarget()!=NULL_KEY&&ready==TRUE)llStartAnimation(anim); } run_time_permissions(integer perm) { llStopAnimation("sit"); if(ready)llStartAnimation(anim); } |
Et pour la fin
Note système fonctionne, mais ça posera des soucis des que l'on s'arrête car note variable ready reste à vrai et donc on considère ainsi qu'il reste toujours un avatar sur le l'autre pose. Et ça se résous en envoyant simplement un message à l'autre pose au moment ou on se lève en lui disant non pas TRUE, mais FALSE.
Voici le script complet pour la fin
string anim; integer ready=FALSE; default { state_entry() { //stock le nom de l'animation qui se trouve dans l'inventaire de la pose ball anim=llGetInventoryName(INVENTORY_ANIMATION, 0); llSitTarget(<0.0,0.0,0.01>, ZERO_ROTATION); } changed(integer change) { key av=llAvatarOnSitTarget(); if(av!=NULL_KEY) { llMessageLinked(LINK_ALL_OTHERS, TRUE, "", NULL_KEY); llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION); } else { llMessageLinked(LINK_ALL_OTHERS, FALSE, "", NULL_KEY); } } link_message(integer sender_num, integer num, string str, key id) { ready=num; if(llAvatarOnSitTarget()!=NULL_KEY&&ready==TRUE)llStartAnimation(anim); } run_time_permissions(integer perm) { llStopAnimation("sit"); if(ready)llStartAnimation(anim); } }
|
Epilogue
Cette pose ball présente encore pas mal de défaut même si elle a le mérite d'être fonctionnelle. Mais je vous laisse trouver comment résoudre tout ça, car vous avez toutes les cartes en mains.
Par Mathew Cazalet