• Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
  • Wir freuen uns, wenn du dich in unserem Forum anmeldest. Bitte beachte, dass die Freigabe per Hand durchgeführt wird (Schutz vor Spammer). Damit kann die Freigabe bis zu 24 Stunden dauern.
  • Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Sie geben Einwilligung zu unseren Cookies, wenn Sie unsere Webseite weiterhin nutzen.

Scripten Lernen (Deutsch)

Wer hat Interesse, Scripte zu verstehen?


  • Umfrageteilnehmer
    19
  • Umfrage geschlossen .

Wolwaner Jervil

Freund/in des Forums
das ist leichter gesagt als getan. Dae hat sich 2 mal die Zeit genommen und ist mit mir alles durchgegangen. Für den Moment verstehe ich einiges auch aber sobald ich dann selbst versuche es umzusetzen, stehe ich wieder am Anfang.
Das ist immer so - was man gesagt bekommt hört sich immer einfacher an als es dann ist. Schrittweise weiter machen, wenn was unklar ist, fragen - ich helfe gerne mit. Inworld IM geht an meine E-Mail oder wir können uns einen Termin ausmachen.
 

Daemonika Nightfire

Forumsgott/göttin
@Marian Dufaux der einfachste Lernprozess ist ausprobieren.
Darum habe ich die Lektion 4 zerlegt, um auszuprobieren was die einzelnen Funktionen ueberhaupt so machen.
Wenn du aus Spass einfach mal die Funktions-Seite der Wiki auf machst und dir irgend welche Befehle heraus suchst, die dir optisch zusagen und damit herum experimentierst, werden dir frueher oder spaeter Gemeinsamkeiten auffallen.

Kleiner Tipp, alle Funktionen folgen dem gleichen Chema.
Bei den Befehlen mit einem offensichtlich ersichtlichen Namen, was sich dahinter verbergen koennte, kannst du dich zu 90% darauf verlassen, das du sie im touch(... Event ausprobieren kannst.
Wenn du das Verstaendniss fuer die Klammern und Semicolons trainieren willst, kopiere die Beispiel-Scripte aus der Wiki nicht einfach heraus, sondern schreibe die von oben nach unten einfach ab. ;)

LG
Dae
 

Marian Dufaux

Freund/in des Forums
Das ist immer so - was man gesagt bekommt hört sich immer einfacher an als es dann ist. Schrittweise weiter machen, wenn was unklar ist, fragen - ich helfe gerne mit. Inworld IM geht an meine E-Mail oder wir können uns einen Termin ausmachen.
Danke für das Angebot. Dae hat sich an mir auch schon die Zähne ausgebissen. Aber ich bedanke mich ganz herzlich bei ihr, dass sie so viel Geduld hatte.
@Daemonika Nightfire und ja ich werde es einfach mal ausprobieren. Gestern hatte ich wieder das Problem, dass mein Sender, also der Hud, natürlich nicht funzte. Ich glaube aber, ich habe den Fehler gefunden. Muss ich nachher mal testen.
 

Wolwaner Jervil

Freund/in des Forums
Vielleicht noch was aus meiner eigenen Programmier-Erfahrung: Bei Problemen haben wir uns immer jemanden geholt und demjenigen den Ablauf erklärt - auch wenn derjenige sonst nicht beteiligt war, wurde im Normalfall der Fehler gefunden.
Also nicht ewig und verzweifelt an einem ding stundenlang rumkäämpfen, sondern miteinander reden.
 

surini

Aktiver Nutzer
ich bin ja froh das uli mitfilmt so kann man sich die videos immer wieder anschauen wenn man was vergessen hat . )
 

Daemonika Nightfire

Forumsgott/göttin
Das ist OK Uli, jeder hat hin und wieder mal was anderes vor, ausserdem machst du das ja auch freiwillig.
Das muss dir nicht Leid tun, niemand hat Anspruch darauf, das du mitfilmst. :)
Schade finde ich nur, das du selber den Kurs verpasst hast. Nichts desto Trotz kannst du dir mein Meispiel in der Schule gern kopieren und wir koennen das mal in kleiner Runde durchgehen, wenn du magst.

Ich habe aber noch vor, das fertige Script und ein kleines Extra hier im Forum zu posten. Das dauert aber noch, da ich diese Woche sehr wenig Zeit habe und erst noch etwas dafuer vorbereiten muss.

LG
Dae
 

Daemonika Nightfire

Forumsgott/göttin
huhu ihr suessen,

tut mir leid das ich schon wieder so spaet dran bin.

Zu aller erst moecht ich mich bei Wolwaner bedanken, dafuer das er die tollen Kommentare ins Script eingefuegt hat, welches ich euch natuerlich nicht vorenthalten moechte.

Im folgenden Script ist es notwendig, die Button der einzelnen Funktionen entsprechend der kategorie alle gleich zu benennen, mit ausnahme der Zahl direkt hinter dem Namen.
Zum beispiel heissen hier die Button wiefolgt.
  • Stoffe 0 , Stoffe 1 , Stoffe 2 , Stoffe 3 und Stoffe 4
  • Metalle 0 , Metalle 1 und Metalle 2
  • Werbung
  • anbehmen
Sender / Hud
Code:
key Owner; // definieren der variablen für den UUID des Owners
integer ObjectChannel = -3456451; // über diesne Kanal kommunizieren die Scripte untereinander
string URL = "https://marketplace.secondlife.com/de-DE/stores/30293"; // diese URL wird im Browser geöffnet

default // default state - da startet alles
{
    state_entry() // wenn das script in diesen state kommt, wird das mal ausgeführt
    {
        Owner = llGetOwner(); // wir füllen die Varable Owner mit der UUID des Owners
        if(llGetAttached() != 0) // wir fragen ab, ob der HUD an einem Attachpunkt hängt. 0=gerezzt
        {
            llRequestPermissions(Owner, PERMISSION_ATTACH ); // Abfrage, ob wir Attach/Detach ausführen dürfen.
        }
    }
    
    run_time_permissions(integer perm) // hier kommen wir auf Grund des permission requests
    {
        if(perm & PERMISSION_ATTACH) // wenn die permission (Erlaubnis) erteilt wurde - im Fall von Attach wird das automatisch gegeben.
        {
            llOwnerSay("Betriebsbereit..."); // verständigen wir mal den Owner
        }
    }

    touch_start(integer total_number) // jemand drückte auf die Maustaste (Touch) und dann läufts hier weiter
    {
        integer LinkNumber = llDetectedLinkNumber(0); // die Link Nummer des berühten Objektes im Linkset
        string LinkName = llGetLinkName(LinkNumber); // der Name des berührten Objektes - auch wenn sich bei einem re-link die Nummern ändern, bleibt der Objektname erhalten.
        
        list ParsedName = llParseString2List(LinkName, [" "], []); // Wir nehmen mal an, dass "Stoffe 2" gewählt wurde und zerlegen das in eine Liste, also ["Stoffe", "2"]
        string Name = llList2String(ParsedName, 0); // und jetzt nehmen wir nur den Namen - "Stoffe"
        // string Number = llList2String(ParsedName, 1);
        
        if(Name == "Stoffe") // oder if(Name == "Stoffe" || Name == "Metalle")
        {
            llSay(ObjectChannel, LinkName); // wenn's Stoffe sind, senden wir "Stoffe 2" weiter in den Channel - den ören alle, die ein Listen für diesen channel aufgesetzt haben
        }
        else if(Name == "Metalle") // ebenso mit den Metallen
        {
            llSay(ObjectChannel, LinkName); // auch weiterschicken
        }
        else if(Name == "Werbung") // wenn's der Werbeknopf war, öffnen wir die gewünschte URL im Browser
        {
            llLoadURL(Owner, "Marketplace", URL); // die URL wird am Anfang definiert - das ist besser für die Wartung
        }
        else if(Name == "abnehmen") // wenn wer auf den schließen Knopf gedrückt hat
        {
            if(llGetAttached() != 0) // zuerst mal sicher stellen, dass wir am avatar hängen
            {
                llDetachFromAvatar(); // und dann abnehmen.
            }
        }
    }
    
    attach(key AvatarID) // hierher kommen wir, wenn der HUD angezogen wird
    {
        if(AvatarID != Owner) // wenn der Avatar nicht auch Owner ist
        {
            llResetScript(); // resetten wir mal das script
        }
    }
    
    on_rez(integer Dae) // wenn jemand den HUD rezzt
    {
        llResetScript(); // machen wir auch ein reset für die Grundstellung
    }
}

Empfaenger / Kleidungsstueck

Code:
key Owner; // definieren der variablen für den UUID des Owners
integer ObjectChannel = -3456451; // über diesne Kanal kommunizieren die Scripte untereinander (muss mit dem HUD übereinstimmen)

// Globale variable - auf die kann von überall zugegriffen werden
list StoffTexturen = ["ccf5029d-5133-c17c-90a2-d88a1200d36b",  // Stoff Rot
                      "f6bd619d-aa54-bbaa-dcf5-456e03204071",  // Stoff kleine Maedchen_Farbe
                      "2b9a2897-1ae4-ea2e-5503-ef44fd624477",  // Stoff Blau
                      "e521c76c-5aaa-d726-b640-87e5af0e0bc6",  // Stoff Gruen
                      "131adb45-737a-6257-0142-bf0965588901"]; // Stoff Gelb

list MetallTexturen = ["3d9a54e2-2080-0f8d-b388-b3abcb04f7e3",  // Metall Gold
                       "9e63d7a9-4fce-8c45-03f3-a5eab99c827f",  // Metall Silber
                       "adf02c18-f5ab-2177-dcc5-f7559f4efe9b"]; // Metall Cupfer

default
{
    state_entry()
    {
        Owner = llGetOwner();
        llListen(ObjectChannel, "", "", ""); // wir horchen auf den oben definierten Kanal
    }

    listen(integer channel, string name, key id, string message) // wenn irgendjemand (id) am channel (channel) die Nachricht (message) sendet, hören wir das hier (in unserem Beispiel "Stoffe 2" - wie im HUD definiert
    {
        if(llGetOwnerKey(id) == Owner) // wir wollen nur die Nachrichten vom Owner haben - hören tun wir alle! Den UUID vom Sender bekommen wir in der variablen id
        {
            list ParsedMessage = llParseString2List(message, [" "], []); // Wir zerlegen die Nachricht wieder in die Teile
            string cmd = llList2String(ParsedMessage, 0); // "Stoffe"
            integer num = llList2Integer(ParsedMessage, 1); // 2
            
            if(cmd == "Stoffe") // wenns die Stoffe sind
            {
                llSetLinkTexture(LINK_THIS, llList2String(StoffTexturen, (integer)num), 3); // zeigen wir die ausgewählte Textur Nr. 2 auf der Fläche (Face) 3 an. AUFPASSEN: Listen fangen bei 0 an zu zählen
            }
            else if(cmd == "Metalle") // genauso für Metalle, aber auf der Fläche (Face) 1
            {
                llSetLinkTexture(LINK_THIS, llList2String(MetallTexturen, (integer)num), 1);
            }
        }
    }
    
    attach(key id) // kennen wir schon vom HUD
    {
        if(id != Owner)
        {
            llResetScript();
        }
    }
    
    on_rez(integer Dae)
    {
        llResetScript();
    }
}

Das aktuelle Beispiel findet ihr auch noch Inworld in der Script Schule fullperm & free to copy.

Ich muss sagen, das Script war schon sehr aufwendig und eigentlich nicht mehr Anfaenger Kurs, doch es freut mich sehr, das es doch verstanden wurde.

Fuer den naechsten Kurs schalten wir wieder einen gang zurueck und witmen uns etwas einfacherem.
Auf allgemeinen Wunsch befassen wir uns mit Message Linked. Das bedeutet Kommunikation zwischen Scripten innerhalb eines Linksets oder eines Links.

Der naechste Kurs findet morgen den 24.6.2018 um 20 uhr wieder auf Bay of Surreality statt.

LG
Dae
 

Daemonika Nightfire

Forumsgott/göttin
Genau, es genuegt ein einziges Bild fuer den ganzen Hud.
Dabei sind der Fantasie keine Grenzen gesetzt und es funktionieren auch Alpha Texturen, um dem Hud eine beliebige Form bzw. Design zu verpassen.
Dadurch spart man sich jede menge Ladezeiten und bekommt keine Meldung, das der Hud viel Speicher beansprucht.

Uebrigens, auf dem Hud kann man mehrere Alpha Texturen uebereinander legen, der Alpha Bug ist dort nicht wirklich existent. ;)

LG
Dae
 

Wolwaner Jervil

Freund/in des Forums
Da am letzten Sonntag die Frage war, wozu man einen Timer verwendet - hier mal Beispiele:
1) Wenn man auf etwas wartet, ist ein timer gut, damit das nicht in alle Ewigkeit passiert. Das gilt für alles, wo der User was tun muss (z.B. Menüauswahl).
2) Ich habe einen Teleport-Hud gemacht, der nach Ablauf einer Zeitspanne weiter teleportiert.
3) Für Spiele-Boxen ist ein Timer interessant, falls der Spieler einfach verschwindet und damit das Spiel nie beendet würde und somit kein anderer Spiele drankommt.
 

Daemonika Nightfire

Forumsgott/göttin
Stimmt, eigentlich benoetigt man immer dann einen Timer, wenn etwas ohne aeussere Einwirkung automatisch ablaufen soll.
Automatisches Starten/Beenden oder automatisches Wiederholen.

Der Event bleibt in jedem Fall der selbe, lediglich was abgefragt und was ausgefuehrt werden soll unterscheidet sich in der Funktionsweise des Objects.

LG
Dae
 

Daemonika Nightfire

Forumsgott/göttin
huhu ihr suessen,

bevor ich es wieder vergesse.
Diesen Sontnag den 22.7.2018 um 20 Uhr findet wieder der ScriptKurs auf Bay of Surreality statt.

Letztes mal war das Thema doch so Abendfuellend, das wir nicht mehr zum Collisions Event gekommen sind.
Das holen wir kommenden Sonntag nach.

LG
Dae
 

Daemonika Nightfire

Forumsgott/göttin
huhu ihr suessen,

im letzten Kurs haben wir uns darueber unterhalten, wie muehseelig es ist, Link-Nummern im Script zu beruecksichtigen.
Fuer kleinigkeiten hat man schnell mal eben die Link-Nummer eingegeben und/oder aktuallisiert.

Sobald das LINK_SET aber groesser und das Script ziemlich umfangreich ist, wird es kompliziert und laestig.
Darum kamen wir auf die Idee am kommenden Sonntag auf dieses Thema einzugehen.
Dabei lernen wir, wie einfach es ist die Link-Nummern im Script zu beruecksichtigen bzw. aktualisieren ganz ohne sie zu manuell anzugeben.

Das Stichwort heisst Link-Name :)
Mit diesem Prinzip arbeite ich schon seit jahren und kann nur sagen, ich moechte nie wieder Link-Nummern von Hand eingeben muessen, wenn das Script groesser ist und ich weiss das sich das LINK_SET aendern kann.

Der naechste Kurs findet am kommenden Sonntag den 2.9.2018 um 20 Uhr auf Bay of Surreality statt.

LG
Dae
 
Zuletzt bearbeitet:

Daemonika Nightfire

Forumsgott/göttin
Dynamisches LINK_SET

huhu ihr suessen,

zu aller erst moecht ich mich erwaehnen, das der Unterricht immer noch spass macht und fleissig mit gemacht wird.
Vielen Dank :)

Fuer alle die gestern Abend nicht dabei sein konnten habe ich hier das Script mit Erklaerungen.
Sollte es dazu Fragen geben, koennen die gern hier im Thread oder Inworld gestellt werden.

Gestern abend hatten wird das Dynamische LINK_SET. Das bedeutet wir muessen keine fixen Link_Nummern mehr vergeben damit das Script den richtigen Link findet.
Die Funktion die wir erstellt haben ist fuer alles moegliche anwendbar.
Als Globale Funktion koennen wir den Code auch aus jedem X-Beliebigen Event heraus abrufen, ohne alles noch mal schreiben/kopieren zu muessen.

Hier nun das Basic Script voellig ohne Kommentare und Schnik Schnak zwecks uebersicht:
In unserem Beispiel heisst der gesuchte Prim im Objectnamen kleingeschrieben test.
Code:
integer Gesuchte_Link_Nummer;
Suchen()
{
    integer Anzahl_Links = llGetNumberOfPrims();
    integer i = 1;
    
    do
    {
        string Link_Name = llGetLinkName(i);
        if(Link_Name == "test")
        {
            Gesuchte_Link_Nummer = i;
        }
    }
    while(++i <= Anzahl_Links);
}

default
{
    state_entry()
    {
        Suchen();
        llSay(0,"Dein Link namens \"" + llGetLinkName(Gesuchte_Link_Nummer) + "\" \nhat die Link-Nummer (" + (string)Gesuchte_Link_Nummer + ")");
    }

    changed(integer change)
    {
        if(change & CHANGED_LINK)
        {
            Suchen();
            llSay(0,"Dein Link namens \"" + llGetLinkName(Gesuchte_Link_Nummer) + "\" hat die Link-Nummer (" + (string)Gesuchte_Link_Nummer + ")");
        }
    }
}


Nun das selbe Script inclusive Erklaerungen der einzelnen Funktionen:
Das Script ist leserlicher, wenn ihr es Inworld in ein Script kopiert.
Code:
integer Gesuchte_Link_Nummer;   // leerer integer fuer unsere unbekannte Link_Nummer
Suchen()    // start unserer globalen Such-Funktion
{
    integer Anzahl_Links = llGetNumberOfPrims();    // Speicherort fuer die Gesamt_Anzahl Links im LINK_SET
    integer i = 1;  // Startpunkt fuer den Counter in der "do while" Schleife (0 waere Sinnlos, da ein LINK_SET mit mehr als 1 Link immer mit 1 beginnt)
    
    do  // Anfang der "do while" Schleife
    {
        string Link_Name = llGetLinkName(i); // Fragt den Namen des aktuell gewaehlten Links nach (i wird mit jedem Durchlauf um 1 erhoeht)
        if(Link_Name == "test") // Vergleicht den Link_Namen mit dem hier festgelegten Namen
        {
            Gesuchte_Link_Nummer = i;   // Fuellt die globale Variable mit der Link_Nummer (i) wenn der Name ueberein stimmt
        }
    }
    while(++i <= Anzahl_Links); // wiederholt hier den gesamten Vorgang, bis die letzte Link_Nummer erreicht wurde
}

default
{
    state_entry()   // loest aus, sobald das Script gespeichert oder resettet wird
    {
        Suchen();   // Startet die globale Such-Funktion (beachte das Semicolon am Ende)
        
        // Chat-Meldung zum ueberpruefen, ob das Script alles richtig macht
        llSay(0,"Dein Link namens \"" + llGetLinkName(Gesuchte_Link_Nummer) + "\" \nhat die Link-Nummer (" + (string)Gesuchte_Link_Nummer + ")");
    }

    changed(integer change) // loest immer dann aus, wenn sich am Object irgend etwas aendert
    {
        if(change & CHANGED_LINK)   // loest nur dann aus, wenn sich das LINK_SET aendert ( Link hinzufuegen, entfehrnen oder drauf setzen)
        {
            Suchen();   // Startet die globale Such-Funktion (beachte das Semicolon am Ende)
            
            // Chat-Meldung zum ueberpruefen, ob das Script alles richtig macht
            llSay(0,"Dein Link namens \"" + llGetLinkName(Gesuchte_Link_Nummer) + "\" hat die Link-Nummer (" + (string)Gesuchte_Link_Nummer + ")");
        }
    }
}


Nun wollten wir nicht nur eine bloede Chat-Meldung, sondern auch sehen das es funktioniert wie es soll.
Zu diesem Zweck haben wird den Touch Event mit einem Schalter hinzugefuegt.

Wenn wir nun das Object anklicken, wird genau der eine Link namens test eingefaerbt.
Dazu haben wir im Befehl llSetLinkColor keine Link_Nummer angegeben, sondern den Namen der globalen Variable, welcher fuer die Link_Nummer steht.

Das Script mit Touch event, aber wieder ohne Kommentare:
Code:
integer Schalter = 0;

integer Gesuchte_Link_Nummer;
Suchen()
{
    integer Anzahl_Links = llGetNumberOfPrims();
    integer i = 1;
    
    do
    {
        string Link_Name = llGetLinkName(i);
        if(Link_Name == "test")
        {
            Gesuchte_Link_Nummer = i;
        }
    }
    while(++i <= Anzahl_Links);
}

default
{
    state_entry()
    {
        Suchen();
        llSay(0,"Dein Link namens \"" + llGetLinkName(Gesuchte_Link_Nummer) + "\" \nhat die Link-Nummer (" + (string)Gesuchte_Link_Nummer + ")");
        
        llSetLinkColor(Gesuchte_Link_Nummer, <1,0,0>, ALL_SIDES);
    }
    
    touch_start(integer NumberOfTouches)
    {
        if(Schalter == 0)
        {
            Schalter = 1;
            llSetLinkColor(Gesuchte_Link_Nummer, <0,1,0>, ALL_SIDES);
        }
        else if(Schalter == 1)
        {
            Schalter = 0;
            llSetLinkColor(Gesuchte_Link_Nummer, <1,0,0>, ALL_SIDES);
        }
    }

    changed(integer change)
    {
        if(change & CHANGED_LINK)
        {
            Suchen();
            llSay(0,"Dein Link namens \"" + llGetLinkName(Gesuchte_Link_Nummer) + "\" hat die Link-Nummer (" + (string)Gesuchte_Link_Nummer + ")");
        }
    }
}


Natuerlich kann man die Funktion beliebig erweitern oder eine andere Schleife als die "do while" verwenden.
Doch ich finde die "do while" Schleife im Anfaenger-Kurs deutlich einfacher und uebersichtlicher als die "for" Schleife.

In diesem sinne bedanke ich mich das alle fleissig mit gemacht haben und wuensch allen bei allen weiteren Kursen viel Spass.
Bis zum naechsten mal in 2 Wochen.

LG
Dae
 

Aktive User in diesem Thread

Oben Unten