Ob beim Einkaufen, Tanzen oder vielen anderen Dingen, bei denen man die Qual der Wahl haben soll: Die zumeist hellblau unterlegten, rechts oben im Viewerfenster erscheinenden Dialogmenüs sind in SL allgegenwärtig. Dass und wie man sie auch selbst basteln kann, wird im nachfolgenden Beispielscript erklärt. Es handelt sich dabei lediglich um ein "sinnfreies" Basisscript, an dem aber das Gerüst recht gut nachvollzogen werden kann. Man kann zwischen fünf Optionen wählen (Tasten 1 bis 5), die eine Ausgabe an den Benutzer per IM veranlassen: "Du hast x gewählt", wobei x für die gewählte Taste steht. Selbstverständlich kann man bei Anwendungen im "richtigen" zweiten Leben an gleicher Stelle im Script viele andere, sinnvollere Funktionen anstoßen lassen. Der Experimentierlaune seien hier keine Grenzen gesetzt. Hier aber erst einmal das Script in seiner einfachsten Form:
Wie allgemein üblich, werden vor Beginn des eigentlichen Scripts globale Variablen - also solche, die im ganzen Script gültig sein sollen - deklariert. Von denen gibt es gleich eine ganze Reihe. Die ersten beiden bestimmen das Aussehen des Dialogmenüs:
dialogText
enthält den erläuternden Menütext, der bis zu 512 Zeichen beinhalten darf.dialogTasten
ist eine Liste mit den Tastenbeschriftungen. Offiziell sind 24 Zeichen erlaubt, aber ich empfehle
ein Ausprobieren, wie viel wirklich dargestellt wird.Die nächsten Variablen sind für die Abhörfunktion des Chats notwendig, über welches die Kommunikation zwischen Benutzer und
Script ablaufen wird. Dieser sogenannte Listener und das von diesem angestoßene Event listen
benötigt folgende Daten:
benutzer
, die UUID des aktuellen Benutzers, die im Event touch_start
ermittelt wird.menuChannel
ist der noch zu ermittelnde Chatkanal. Dessen Ermittlung erfolgt im Event
state_entry
durch Ermitteln eines zufälligen Kanals mit negativem Vorzeichen, auf dem mit an Sicherheit
grenzender Wahrscheinlichkeit gerade keine andere Kommunikation abläuft. Der für alle sichtbare Chat-Kanal 0 sollte tunlichst
vermieden werden, ansonsten kann man beinahe jeden beliebigen Kanal wählen.listener
ist ein Funktionswert, der zur Aktivierung des Events listen
benötigt wird.
Lässt man sich während der Laufzeit des Scripts diese Ganzzahl anzeigen, handelt es sich nur um eine schnöde 1. Doch hinter
den Kulissen werden vier Werte an den Server übergeben, die für den Betrieb des Listeners benötigt werden und wie ein Filter
wirken. Selbst wenn man wie in unserem Fall auf die zweite (konkreter Name eines Avatars oder eines Objekts) und auf die
vierte (Signalwort) verzichtet, müssen hierfür zumindest leere Stellen als "" übergeben werden.Schließlich wird noch eine abschaltzeit
festgelegt. Sie gibt den Wert vor, nach dem durch das Event
timer
der lag-verursachende Listener wieder geschlossen werden soll und das Script in den
Bereitschaftsstatus zurückkehrt.
Noch bevor das Script überhaupt ausgeführt wird, werden durch vor dem State default
geschriebene
selbstdefinierte Funktion abStopListenerTimer ()
Vorkehrungen getroffen, sowohl den Listener als auch den Timer
abzuschalten. Auch der Wert für den Funktionswert listener
wird auf null zurückgesetzt. Der Sinn dürfte klar sein:
Schonung von Serverressourcen und damit Lag-Vermeidung!
Das Hinterlegen dieser drei Aktionen in einer selbstdefinierten Funktion erscheint deshalb sinnvoll, weil sie an zwei Stellen im Script ausgeführt werden soll: Entweder nach erfolgter Eingabe über das Dialogmenü oder nach Ablaufen des Timers, wenn es zu keiner Bedienung gekommen ist.
Dreh- und Angelpunkt für die Aktivierung der Dialogfunktionen ist das Event touch_start
. Nachdem der Funktionswert
listener
sein Wertepaket durch llListen
erhalten hat, erfolgt
der Aufruf des Dialogmenüs über die Funktion llDialog
. Der Einleitungstext, die Texte für die Tasten
sowie der Eingabekanal sind bereits in den globalen Variablen festgelegt worden. Zwar könnte man sie auch hier direkt eingeben,
aber zum Bearbeiten von Einträgen erscheint es mir einfacher, diese an prominenter Stelle zu vereinen.
Die Sortierung der Tasten im Menü ist übrigens etwas eigenwillig, wie sich unschwer erkennen lässt: Von links nach rechts,
aber von unten nach oben. Mehr als 12 Tasten kann eine einzelne Dialogmenü-Seite nicht anzeigen. Möchte man die Sortierung in
einer Weise vornehmen, die unseren Seh- und Nutzungsgewohnheiten mehr entspricht, muss man eine numerische Beschriftung der Tasten
in der Liste wie folgt vornehmen: [10, 11, 12, 7, 8, 9, 4, 5, 6, 1, 2, 3]
Braucht man mehr als 12 Tasten, muss man ein mehrseitiges Menü erstellen. Doch dies ist nicht ganz trivial und wäre im Moment noch etwas zu ambitioniert. Dasselbe gilt für das automatisierte Umsortieren von numerischen Beschriftungen.
Sollte nach der durch den Wert von abschaltzeit
festgesetzte Zeit noch keine Eingabe erfolgt sein, springt das
Script in das Event timer
, das abStopListenerTimer ()
auslöst. Das Dialogmenü
bleibt zwar auch Ablauf der Zeit stehen, eine Bedienung führt allerdings nur zu dessen Verschwinden. Ein Infotext klärt darüber
auf, wie man doch noch eine Eingabe tätigen kann.
Das Event listen
beinhaltet jene Teile des Scripts, die für das Abarbeiten der vom Server übergebenen
Variablen message
enthaltenen Information zuständig sind. Einfacher gesagt: Die Tastenbedienung wird in Beziehung
mit einer auszuführenden Aktion gesetzt - also im Prinzip dasselbe, was wir schon beim Wechselschalter kennengelernt haben:
"Wenn Du X gedrückt hast, mache dies. Wenn Du Y gedrückt hast, mache etwas anderes." Nur in diesem Falle nicht nur für zwei,
sondern für einige weitere Wahlmöglichkeiten. In diesem einfachen Beispiel wird nur der Wert angezeigt, der gedrückt worden ist.
Was unterscheidet aber if
von else if
? Man könnte doch solch eine Abfrage auch als Serie
ausschließlich aus if-Abfragen aufbauen.
Das stimmt zwar, jedoch würde auch nach Erfüllung einer Bedingung - z.B. der Betätigung der Taste "2" - die Kette weiter
durchlaufen werden, bis sie beim letzten Wert angekommen wäre. Bei Verwendung von else if
hingegen bricht die
Abfrage ab, sobald eine zutreffende Bedingung gefunden worden ist. Dadurch spart man Zeit und Serverressourcen!
Abschließend folgt noch der Aufruf der selbstdefinierten Funktion abStopListenerTimer ()
, denn sowohl die Dienste
von Listener als auch Timer werden nun einstweilen nicht mehr benötigt.
Im der nächsten Lektion lernen wir eine konkretere Anwendung am Beispiel eines einfachen Resizers kennen, das Größenänderungen an Objekten ohne Öffnen des Baumenüs erlaubt.