Le LSL de Second Life

Ce site est consacré principalement au langage LSL de Second Life...

« Retour aux scripts


Mobile


Faire se déplacer un objet dans SL est à la fois simple et délicat. Je vous propose un script qui permet d'automatiser cela. Mettez simplement ce script dans l'objet à déplacer qui doit pouvoir passer en "physique", autrement dit ne pas comporter plus de 32 primitives.

//------------------------------------------------

//

// Simple Mobile V 1.0

//

// -----------------------------------------------

// Variables de paramétrage

// -----------------------------------------------

string nomNote = "Config";

// -----------------------------------------------

// Variables de travail

// -----------------------------------------------

integer canalCommand = 0;

integer ecouteCommand = 0;

integer notecardLine = 0;

integer index = 0;

integer resume = FALSE;

list commandes = [];

vector posBase = ZERO_VECTOR;

rotation rotBase = ZERO_ROTATION;

// -----------------------------------------------

// Récupération liste d'une entrée de commande

// -----------------------------------------------

list getList() {

string s = llStringTrim(llList2String(commandes, index), STRING_TRIM);

return llParseString2List(s,["|"],[]);}

// -----------------------------------------------

// Récupération délai

// -----------------------------------------------

float getTime() {return (float)llList2String(getList(), 1);}

// -----------------------------------------------

// Récupération canal

// -----------------------------------------------

integer getChannel() {return (integer)llList2String(getList(), 1);}

// -----------------------------------------------

// Récupération commande

// -----------------------------------------------

string commande() {return llStringTrim(llList2String(getList(), 0), STRING_TRIM);}

// -----------------------------------------------

// Translation supérieure à 10 mètres

// -----------------------------------------------

object_move_to(vector position) {

vector last;

do {

last = llGetPos();

llSetPos(position);

} while ((llVecDist(llGetPos(),position) > 0.001) && (llGetPos() != last));

}

// -----------------------------------------------

// Avancée

// -----------------------------------------------

go(){

list l = getList();

float length = (float)llList2String(l, 1);

float sens = 1.0;

if(length < .0) {

sens = -1.0;

length = -length;}

float v = (float)llList2String(l, 2);

float time = length / v;

llSetStatus(STATUS_ROTATE_X | STATUS_ROTATE_Y | STATUS_ROTATE_Z, FALSE);

llSetStatus(STATUS_PHYSICS, TRUE);

integer targetID;

integer n = llCeil(time / 2.0);

float x = length / (float)n;

float tt = time / (float)n;

vector myPos = llGetPos();

integer c;

vector t;

for(c = 1; c <= n; c++) {

t = myPos + sens * <(float)c * x,.0,.0> * llGetRot();

targetID = llTarget(t, .01);

llMoveToTarget(t, tt);

llSleep(tt);}

llSleep(1.0);

llTargetRemove(targetID);

llStopMoveToTarget();

llSetPos(t);

llSetStatus(STATUS_PHYSICS, FALSE);}

// -----------------------------------------------

// Rotation

// -----------------------------------------------

goRot() {

list l = getList();

float anglex = ((float)llList2String(l, 1)) * DEG_TO_RAD;

float angley = ((float)llList2String(l, 2)) * DEG_TO_RAD;

float anglez = ((float)llList2String(l, 3)) * DEG_TO_RAD;

float vitesse = ((float)llList2String(l, 4)) * DEG_TO_RAD;

rotation rot = llEuler2Rot(<anglex, angley, anglez>);

vector axe = llRot2Axis(rot);

float angle = llRot2Angle(rot);

float t = llFabs(angle / vitesse);llOwnerSay((string)t);

float stepAngle = angle / (t / .02);

integer n = llRound(t / .02);

rotation stepRot = llAxisAngle2Rot(axe, stepAngle);

float strength = llGetMass() / 2.0;

rotation endRot = rot * llGetRot();

integer c;

for(c = 0; c < n; c++) {

llRotLookAt(stepRot * llGetRot(), strength, .02);

llSleep(.02);}

llSetRot(endRot);}

// -----------------------------------------------

// Etat par défaut attente note Config

// -----------------------------------------------

default

{

state_entry() {

if(llGetInventoryType(nomNote) != INVENTORY_NONE) {

llOwnerSay("Reading Notecard...");

llGetNotecardLine(nomNote, notecardLine++);}

else

llOwnerSay("Waiting for notecard " + nomNote);}

dataserver(key id, string data) {

if (data != EOF) {

if(llSubStringIndex(data,"//") == -1 && data != "") {

llOwnerSay(data);

commandes += data;

if(commande() == "CHANNEL") {

canalCommand = getChannel();

commandes = [];}

}

llGetNotecardLine(nomNote, notecardLine++);}

else {

llOwnerSay("Config Notecard read. Mobile ready.");

state attente;}

}

changed(integer change) {

if(change & CHANGED_INVENTORY)

if(llGetInventoryType(nomNote) != INVENTORY_NONE) {

llOwnerSay("Reading Notecard...");

notecardLine = 0;

llGetNotecardLine(nomNote, notecardLine++);}

}

}

// -----------------------------------------------

// Etat attente

// -----------------------------------------------

state attente

{

state_entry() {

if(resume) {

resume = FALSE;

state gestion;}

if(canalCommand) ecouteCommand = llListen(canalCommand, "", NULL_KEY, "");

index = 0;}

listen(integer channel, string name, key id, string message) {

state gestion;}

touch_start(integer total_number) {

if(canalCommand) return;

state gestion;}

changed(integer change) {

if (change & CHANGED_INVENTORY) llResetScript();}

state_exit() {if(ecouteCommand) llListenRemove(ecouteCommand);}

}

// -----------------------------------------------

// Etat gestion séquence

// -----------------------------------------------

state gestion

{

state_entry() {

posBase = llGetPos();

rotBase = llGetRot();

integer n = llGetListLength(commandes);

for(index = 0; index < n; index++) {

string c = commande();

if(c == "STOP") llSleep(getTime());

else if(c == "GO") go();

else if(c == "ROT") goRot();

else if(c == "RESUME") {

resume = TRUE;

state attente;}

else if(c == "BACK") {

object_move_to(posBase);

llSetRot(rotBase);

state attente;}

}

}

changed(integer change) {

if (change & CHANGED_INVENTORY) llResetScript();}

}

Il faut ensuite faire une notecard que l'on appelle "Config" avec cette structure et un exemple d'utilisation :

// All the commands :
// CHANNEL | [value] -> channel number for chat command, only if chat command
// GO | [length] | [speed] -> length in meters and speed in meters per seconds
// ROT | [angleX] | [angleY] | [angleZ] | [speed] -> angle in degrees and speed in degrees per seconds
// STOP | [time] -> time in seconds
// BACK -> back to start
// RESUME -> New start


GO | 10 | 1
ROT | 0 | 0 | 90 | 30
GO | 10 | 2
STOP | 4
ROT | 0 | 0 | -45 | 45
GO | 14.14 | 1.5
BACK

Cliquez sur l'objet et regardez le résultat. Je pense que le tout est suffisamment intuitif. Vous pouvez, à partir de cette base, envisager d'autres réalisations.


« Retour aux scripts