SL - Forum scripts

[Guide] LSL 101: Guide du scripteur débutant

Fil fermé
Partager Rechercher
Tables des matières :

Chapitre 1: Hello Avatar !
Chapitre 2: Etats et événements
Chapitre 3: Syntaxe
Chapitre 4: Variables
Chapitre 5: Logique
Chapitre 6: Une introduction aux paramètres des primitives
Chapitre 7: Une Poseball simple

Appendice 1: A faire et a ne pas faire en codage
Appendice 2: Erreurs communes

Si vous n'avez aucune expérience du codage, ne vous inquiétez pas ! Ce guide est écrit dans cet esprit.

Ps : le chapitre en cours de traduction est en italique et en gras.
Chapitre 1: Hello, Avatar !
Citation :
Au commencement, il y avait seulement Philip Linden.
Philip regardait fixement les sims vides,
Exempte de vie et de personnes,
Et cela était triste.


Alors, Philip eu une idée.
Peuplant le vaste monde avec des personnes,
Philip choisi de leur donner le pouvoir de changer le monde.
Ce pouvoir tenait en un mot.


Ce mot était "LSL."
Et cela était bon.
Créer un script :

Il y a 3 manières de créer un script :

1. Faites un clic droit sur le sol, et choisissez "Create" dans le menu radial. Un cube va apparaître ainsi que la fenêtre "Edit". Choisissez l'onglet "Content", cliquez sur le bouton "More" puis sur le bouton "new script". La fenêtre de l'éditeur devrait alors s'ouvrir.

2. Faites un clic droit sur un répertoire de votre inventaire et choisissez "new script". Double cliquez sur le fichier de script qui est apparut et la fenêtre de l'éditeur devrait alors s'ouvrir.

3. Créez votre script dans un éditeur externe puis copiez/collez le dans SL selon l'une des méthodes ci dessus.

Mais qu'est ce donc ? Du code est apparu.

Il devrait ressembler à cela :

Code:
default
 {
 	state_entry()
 	{
 		llSay(0, "Hello, Avatar!");
 	}
 
 	touch_start(integer total_number)
 	{
 		llSay(0, "Touched.");
 	}
 }
L'introduction classique en programmation est un programme qui dit "Hello, world!". Il vous donne un point de départ pour construire vos propres programmes.

Ne paniquez pas, cela est plus facile que cela en a l'air.

L'état default (Default State)

La première chose que vous voyez dans votre nouveau script est le mot "default". C'est ce que nous appellerons un état (state). Chaque script en LSL doit contenir un état Default avec du code à l'intérieur pour fonctionner correctement. Un script peut contenir de multiples états mais nous verrons cela plus tard.

L'état Default contient le code qui est exécuter en premier. "default" dit au compilateur (le programme qui convertit votre code en quelque qui va s'exécuter dans SL) "ok les gars, on va commencer par ici." Sur la ligne suivante, vous voyez une accolade ouverte ({). Cela dit au compilateur que l'information après elle est contenu dans l'état default. Si vous suivez le bord de l'écran vers le bas, vous allez trouver l'accolade fermée de l'état default (}) sur la dernière ligne du script. L'accolade fermée dit au compilateur "le code de l'état default se termine ici". L'espace entre un couple d'accolade est appelé un scope (ou bloc).

Un bloc peut contenir d'autres bloc. Dans cette exemple, le bloc default contient les blocs state_entry et touch_start. Comme vous pouvez le voir, chaque bloc a ses propres accolades ouvertes et fermées. Tous les blocs ouvert avec une accolade doivent être fermés, ou sinon vous obtiendrez une "Syntax error" quand vous allez sauvegarder votre script.

Vous voyez, ce n'est pas si dur !

Evenements (event)

Un évènement est un bloc qui est déclenché par quelque chose qui arrive dans SL.

Event state_entry

Le premier bout de code qui fait quelque chose est inclue dans le bloc de l'évènement state_entry. Jetons un coup d'oeil de plus près :

Code:
state_entry()
 {
 llSay(0, "Hello, Avatar!");
 }
Quand le script entre dans son état default, cela déclenche l'évènement state_entry. Et donc le code du bloc state_entry est la première chose qui est exécuté.

Le nom de l'évènement est suivie par une paire de parenthèse. Pour le moment, laissons leur leur un goût de mystère ! Une paire d'accolades marque le début et la fin du bloc state_entry. Une déclaration est contenue dans ce bloc.

Déclarations (Statements)

La ligne commençant par "llSay" est une déclaration. Les déclarations sont des morceaux de texte qui font quelque chose. Chaque déclarations doit se terminer par un point-virgule ( ; ). Pensez au point-virgule à la fin de vitre déclaration comme au point à la fin d'un phrase (et pensez au compilateur comme à un professeur de grammaire tatillon.). Habituellement, chaque déclaration consiste en une simple ligne de texte.

Sauver le script

Dans l'éditeur, cliquez sur "save". Cela compile et reset le script. Si le script est dans un objet sur le sol, vous devriez voir dans le chat un message comme celui ci :

Object: Hello, Avatar!

Non l'objet ne dit pas bonjour par coïncidence. Cela arrive parce que reseter le script déclenche l'évènement state_entry qui contient la déclaration qui commence avec llSay.

Persistance

Maintenant, dans l'esprit de la science, vous avez touché l'objet pour voir s'il dit "Hello, avatar !" encore. Au lieu de cela, il dit "Touched." Cela réponds à l'évènement touch_start . Pourquoi est ce que l'évènement state_entry ne réponds pas ?

1) Vous avez touché l'objet, donc c'est cet évènement qui réponds.
2) Notre script ne s'est pas terminé. Il est toujours dans l'état default, et rien ne s'est passé qui déclencherais l'évènement state_entry à nouveau. Meme si vous quittez SL et que vous vous reconnectez, vous trouverez toujours votre script dans son état default.

Un script LSL est "persistant." Son état persiste dans le temps. Les valeurs courantes de ses variables persistent également. Vous pouvez le reseter, bien sur, mais vous ne pouvez pas le stopper. Un script LSL cesse de persister uniquement si vous :

1) Effacez le script de l'objet qui le contient.
2) Enlevez l'objet conteneur de SL en le supprimant.

Fonctions


La déclaration commençant avec llSay est un appel de la fonction llSay. Une fonction est un bloc qui fait quelque chose d'intéressant quand vous lui donnez les informations dont elle a besoin.

Toute fonction dont le nom commence avec 2 L minuscules est une fonction Linden qui réside dans l'environnement de SL. Ces morceaux de codes sont crées par les Lindens pour fournir aux scripteurs de nouvelles possibilités.

Passage de paramètres

Les informations que vous donnez à une fonction sont appelés des paramètres.

Quand vous appelez une fonction et que vous lui donnez des informations, vous lui "passez des paramètres. Ces paramètres sont passés entre parenthèses (()). Les parenthèses et les paramètres qu'elles contiennent forment une liste de paramètres.

Les blocs ont besoin d'informations variées. Pour que cela fonctionne, vous devez passer les paramètres dont il a besoin dans l'ordre ou il les attends. Si vous passez plus d'un paramètres, séparez chacun d'eux avec une virgule. Si un paramètre est optionnel, et que vous ne l'incluez pas, le bloc lui assignera une valeur par défaut.

Si vous voulez ne passer aucuns paramètres, mettez une paire de parenthèses vides. La liste de paramètres vide dit au bloc "Ne me regarde pas ! Tu va devoir trouver tes paramètres ailleurs." (Maintenant vous commencer a suspecter le rôle des parenthèses dans l'évènement state_entry() !)

Function llSay

Dissecquons llSay ! (ou plus précisément notre appel de la fonction llSay.)

state_entry()
{
llSay(0, "Hello, Avatar!");
}

llSay est une fonction qui parle sur un canal qui peut être "entendu" par des objets ou des avatars dans un rayon de 20 mètres.

llSay attend que vous lui donniez 2 paramètres, le canal sur lequel parler et le texte a prononcer. Les avatars parlent sur le canal 0, c'est pourquoi "Hello, Avatar!" apparais sur votre écran et dans la fenêtre de chat quand le script est réinitialisé. Les objets peuvent parler sur des canaux autres que le 0, mais cela n'apparais pas à l'écran. Les canaux autres que le 0 sont pratiques pour des communications privées entre 2 (ou plus) objets.

Le texte à prononcer est encadré par des double quotes ("). Cela dit au compilateur "Tout le texte entre ces doubles quotes est une valeur simple. Prends le littéralement et donne le a la fonction tel quel."

Souvenez vous de terminer la déclaration avec un point virgule ( ! Oublier le point virgule est une erreur commune en LSL. (NDT : Pas qu'en LSL d'ailleurs ^^)

évènement touch_start

L'évènement suivant que vous voyez est touch_start. A proprement parler, cet évènement ne contribue en rien au fait de dire "Hello, Avatar !" Apparament, Philip, dans sa sagesse, réalisa que les débutants aimerais voir différents type d'évènements. Ce code est très similaire au précédant :

touch_start(integer total_number)
{
llSay(0, "Touched.");
}

Cet évènement ressemble a un appel de fonction parce que son nom est suivit d'une liste de paramètres. Actuellement, un évènement est apparenté a une fonction plutôt qu'a un appel de fonction. (Vous n'avez jamais vu une fonction. Comment l'auriez vous su ?) Au lieu de paramètres, cette liste contient une variable: integer total_number.

Comme avec une fonction, cette variable est configurée à la valeur d'un paramètre. Une différence intéressante; Second Life lui-même fournit les paramètres pour des événements ! C'est très utile, particulièrement dans les événements comme money. Dans ce cas-ci, le total_number définit le nombre de personnes touchant l'objet à ce moment-là. Les avantages de savoir le nombre de "toucheurs" peuvent sembler douteux en ce moment ! Veuillez garder à l'esprit que nous avons besoin de ce nombre pour des fonctions detected, et qu'un jour vous pouvez être heureux de le savoir !
Mais maintenant, tout ce que nous faisons c'est appeler la fonction llSay pour dire "Touched" chaque fois que qqun touche l'objet. Nous passons à llSay une liste de paramètre tout comme celle que nous avons employée avant : canal 0, et texte "touched".

Félicitations ! Vous avez avec succès déchiffré votre premier script !
Chapitre 2: Etats et événements
Citation :
Whoever desires to found a state and give it laws, must start with assuming that all men are bad and ever ready to display their vicious nature, whenever they may find occasion for it.

Nicollo Maciavelli
Architecture du LSL

Un script LSL est composé de :
  • optionnellement, des variables globales and des fonctions. (Mais vous n'êtes pas encore supposé les connaître)
  • Au moins un état, nommé "default". En option, des états additionnels.
  • Des événements avec chaque état.

Prenons le script Hello Avatar ! comme exemple et voyons a quoi il ressemble dans une matrice.

Code:
default
{
    state_entry()
    {
        llSay(0, "Hello, Avatar!");
    }

    touch_start(integer total_number)
    {
        llSay(0, "Touched.");
    }
}
EvenementDefault
state_entrySay Hello Avatar
touch_startSay Touched

Deux états, wahouu

Voici un autre exemple: la boite à chatouillis. La première fois que vous la touchez, elle vous demande de la toucher à nouveau. La seconde fois, elle vous remercie. Sa matrice ressemble à ceci :

EvenementDefaultTickled
touch_startSay Now, touch me again.
Enter state tickled
Say Thank you! That felt good.
Enter state default

De quelles techniques avons nous besoin pour écrire le script de la boite à chatouillis que nous n'avons pas déjà vu dans le script Hello Avatar ?
  • Un moyen de définir un second état.
  • Un moyen de passer d'un état à un autre.

Comment définir plusieurs états

Alors pour définir un état, il faut précéder le nom de l'état du mot "state" (sauf pour default qui n'en a pas besoin)

Voici comment définir l'état "tickled"

Code:
state tickled
{
...
}
Mettre les accolades et écrire le code qui va dedans est une bonne habitude, cela permet de ne pas en oublier.

Comment aller d'un état à un autre

Dans l'événement approprié dans l'état #1, utilisez la commande state pour entrer dans l'état #2. Par exemple :

Code:
state tickled;
Le challenge de la boite à chatouillis

Vous pensiez trouver le script de la boite à chatouillis ici ? tss tss, au boulot, allez in-world, créez une box ainsi que le script dont nous parlons.

  • Dans l'onglet content, créez un nouveau script, vous obtenez un le script template "Hello, Avatar!".
  • Editez le, copiez les parties dont vous avez besoin et effacez celles qui vous semble inutiles.

Allez, je vous donne la solution quand même mais cherchez un peu avant de la regarder.

Code:
Cliquez ce bouton ou survolez le contenu pour afficher le spoiler
default { touch_start(integer total_number) { llOwnerSay("Now, touch me again."); state tickled; } } state tickled { touch_start(integer total_number) { llOwnerSay("Thank you! That felt good."); state default; } }
Bonjour à tous ...

En lisant cet intéressant Post et en voyant de nouveau les éternelles questions que semblent poser les HUDs et j'ai décidé de ré-ouvrir mon éditeur de scripts resté clos depuis de nombreux mois..si si!

Je vais essayer de faire court..

Un Hud n'est ni plus ni moins qu'un simple objet attaché à l'écran (1 prim ) ...mais de dimensions adaptées à ce dernier.

Il contient un ou plusieurs scripts nécessaires à la relation avec l'utilisateur et en général il va interférer l'avatar ou un objet.

Pas compliqué non?



Pour rendre les choses les plus simples possibles j'ai créé un premier script tout simple qui aura la charge entre autre à partir d'un cube standard de:

déterminer la taille en fonction de son attachement

créer x zones pouvant être touchées et donc interactives ( touches virtuelles)

afficher un quadrillage permettant de voir les touches.

Assez de bla bla une de la réalisation d'un HUD 4 x 4 ( 16 touches)

Pièce jointe 81673

Dans le post si j'ai bien suivi il est demandé de d'avoir la possibilité de:

Envoyer un texture à une fenêtre

rendre opaque ou pas cette dernière

ce qui fait 3 boutons ...comme il faut être prévoyant disons 4 boutons...


ce qui donne en paramétrant le script

Pièce jointe 81674


Voila pour le HUD est construit... physiquement ouf!


Pour localiser la zone cliquée sur le HUD il existe une fonction bien utile

Code PHP:

        vector UV llDetectedTouchST(0); 

Maintenant comment transmettre une Image dans un premier temps au HUD?


le plus simple de mon avis ... est de faire glisser une texture sur le HUD... et de capter son UUID et le tour est joué.

Code PHP:

    changed(integer change)
    {
        if (
change CHANGED_TEXTURE
        {
            
Texture_Loaded llGetTexture(4);     
        }
    } 
Je suis assez adepte du multi scripts et non d'un seul script qui rassemble toutes les fonctions...

le premier script va donc déterminer la touche ( virtuelle) cliquée et l'adresser au second script qui lui aura la charge de transmettre à la fenêtre quelques ordres...

les fonctions llMessageLinked et link_message se montreront parfaites...


Maintenant les scripts du HUD:

Master Script HUD:

Code PHP:

string      Texture_Loaded "";
string      Texture "088b56c1-5127-a1dd-148b-4ca1aa2b361c";

vector      White_Color = <1.0,1.0,1.0>;
vector      Size_HUD_On     = < 0.010.150.15 >;
vector      Size_HUD_Off    = < 0.050.400.40 >;

vector      Repeats = < 1.01.01.0 >;
vector      Offsets = < 0.00.00.0 >;

float       Rotation_in_radians 0;
float       Alpha 1;
    
integer     Number_Ranges  4;
integer     Number_Columns 1;

float       Size_Columns ;
float       Size_Ranges ;
vector      Size_HUD;
list 
keys;

init_texture()
{
    
    
Repeats.Number_Columns;
    
Repeats.Number_Ranges;
    
     if (
Number_Columns%2)
        
Offsets..0
    else 
        
Offsets.0.5;        
         
    if (
Number_Ranges%2)
        
Offsets.0
    else
        
Offsets.0.5;         
 
    
    
integer i;
    
integer j;
    
integer k;

    
keys = [];
    
    for ( 
j  <= Number_Ranges )
    {
        for ( 
i  <=  Number_Columns )
        {
            
j*10 i;
            
keys += k;
        }
    
    }
    
    
llSetPrimitiveParams([  PRIM_TEXTUREALL_SIDES,  Texture,  Repeats,  OffsetsRotation_in_radians ] );
}


default
{
    
state_entry()
    {
        
Size_HUD Size_HUD_On;  // par defaut une taille  
        
        
llSetPrimitiveParams([  PRIM_TYPE
                                    
PRIM_TYPE_BOX
                                    
PRIM_HOLE_DEFAULT,  
                                    <
0.001.00.0>,   // cut
                                    
0.0,                // hollow
                                    
<0.00.00.0>,    // twist
                                    
<1.01.00.0>,    // top_size
                                    
<0.00.00.0>,     // top_Shear
                                
PRIM_SIZE,
                                    
Size_HUD
                                
PRIM_FULLBRIGHT
                                    
ALL_SIDES
                                    
TRUE
                                
PRIM_COLOR
                                    
ALL_SIDES
                                    
White_Color
                                    
Alpha 
                                
]);
                                
        
llSetObjectName "Generic HUD");
        
init_texture();  

    }
    
    
attach(key id)
    {
        if(
id)//tests if it is a valid key and not NULL_KEY
        
{
            
Size_HUD Size_HUD_On// Si c'est un attachement...
        
}
        else
        {
            
Size_HUD Size_HUD_Off;
        }
        
         
llSetScaleSize_HUD );

    }

    
touch_start(integer total_number)
    {


        
integer     range;
        
integer     colum;
        
        
Size_Columns = (1.0 Number_Columns);
        
Size_Ranges =  (1.0 Number_Ranges); 
        
        
vector UV llDetectedTouchST(0);

        
colum llCeil (UV.Size_Columns);
        
range llCeil (UV.Size_Ranges);

        
integer key_number =  llListFindList(keys,[ range 10 colum ]);
   

        
llMessageLinked(LINK_THIS,key_number,Texture_Loaded ,"");

  
    }
    
    
changed(integer change)
    {
        if (
change CHANGED_TEXTURE
        {
            
Texture_Loaded llGetTexture(4);     
            
llSetPrimitiveParams([  PRIM_TEXTUREALL_SIDES,  Texture,  Repeats,  OffsetsRotation_in_radians ] );
        }
    }


Sender HUD

Code PHP:

integer     Channel_window 20090812;

default
{

    
link_message(integer sender_numinteger numstring msgkey id
    {
        if (
num == 1
        {
            if (
msg == ""
                
llOwnerSay "NO texture found... drag one on the HUD");
            else
                    
llSay(Channel_window,(msg));
        }
        else if (
num == 2
           
llSay(Channel_window,"White");
        else if (
num == 3
            
llSay(Channel_window,"Black");
        
//else if (num == 4) 
            //ICI on met les commandes pour chaque touche supplementaire....
    
}

Pour la fenètre:

j'ai pris l'hypothèse qu'il pouvait en avoir plusieurs ... liées au pas ...


le script

Listening HUD

Code PHP:

integer listen_handle;
integer Channel_Hud 20090812;
vector  White_Color = <1.0,1.0,1.0>;
vector  Black_Color = <0.0,0.0,0.0>;
float   Alpha 1;
 
default
{
    
state_entry()
    {   
        
listen_handle llListen(Channel_Hud"""""");
    }
    
listeninteger channelstring namekey idstring message )
    {
         if (
llStringLength (message) == 36 )
            
llSetLinkTexture(LINK_SET,message ALL_SIDES);
         else 
            {
                if ( 
message == "Black" 
                    
llSetLinkPrimitiveParams(LINK_SET,[ PRIM_COLORALL_SIDESBlack_ColorAlpha ] );
                else if ( 
message == "White" 
                    
llSetLinkPrimitiveParams(LINK_SET,[ PRIM_COLORALL_SIDESWhite_ColorAlpha ] );
        }

    }


En final methode:


1. Créer un cube et insérer les 2 scripts:

Master Script HUD
et
Sender HUD

2. Prendre cet object et l'attacher à l'écran

Le HUD est READY!


3. Insérer le script dans le/les fenêtres
Listening HUD


Ensuite glisser une photo sur le HUD puis touche 1 ( celle du bas)

les touches 2 et 3 sont l'opacité ou pas de la texture.

Photo finale:

Pièce jointe 81678


NB:

Les scripts ont été faits ( trop rapidement!) dans un but pédagogique et didacticiel... pas plus pas moins... cependant ils peuvent être une bonne base de départ...

Les +++ des 2 scripts du HUD sont la possibilité de créer un HUD de x touches en dynamique (bien utile en phase de développement) par les paramétrages de

Code PHP:

integer     Number_Ranges  4;
integer     Number_Columns 1
et d'adresser des ordres bien sûr à un objet distant....

J'ajouterai quelques commentaires dans les scripts ...
Miniatures attachées
Cliquez sur l'image pour la voir en taille réelle

Nom : HUD Demo3.png
Taille : 878x438
Poids : 104,8 Ko
ID : 81684   Cliquez sur l'image pour la voir en taille réelle

Nom : HUD DEMO2.png
Taille : 402x459
Poids : 31,5 Ko
ID : 81685   Cliquez sur l'image pour la voir en taille réelle

Nom : HUD DEMO1.png
Taille : 865x840
Poids : 120,2 Ko
ID : 81686  
Fil fermé

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés