16.02.2026, 10:02
Ein LSL-Skript, mit dem du jedes Bento-Gelenk eines Avatars einzeln bewegen und testen kannst
Verwendung
1. Skript in ein beliebiges Prim legen (z.B. ein HUD oder ein Objekt in der Hand)
2. Avatar auswählen: Klicke das Objekt an, während du den zu testenden Avatar trägst
3. Steuerung über Chat-Befehle (Channel 1):
- `/1 next` - Nächstes Gelenk
- `/1 prev` - Vorheriges Gelenk
- `/1 list` - Alle verfügbaren Gelenke anzeigen
- `/1 [Gelenkname]` - Bestimmtes Gelenk auswählen (z.B. `/1 mHead`)
- `/1 rot X Y Z` - Rotation in Grad setzen (z.B. `/1 rot 0 45 0`)
- `/1 pos X Y Z` - Position in Metern setzen (Offset)
- `/1 reset` - Aktuelles Gelenk zurücksetzen
- `/1 clear` - Alle Overrides löschen
Wichtige Hinweise
- Das Skript verwendet **Prim Property Overrides**, um die Gelenke zu bewegen
- Der Avatar muss **Bento-kompatibel** sein
- Einige Gelenke funktionieren nur, wenn der Avatar sie tatsächlich besitzt
- Die Rotation wird in **Grad** angegeben (nicht Radianten)
- Das Skript zeigt immer das aktuell ausgewählte Gelenk und dessen Werte als HUD-Text an
Das Skript ist ideal zum Testen von Bento-Rigging und Animationen!
PHP-Code:
// Bento Avatar Gelenk-Tester
// Steuerung über Chat-Befehle
// Liste der wichtigsten Bento-Gelenke
list BENTO_JOINTS = [
"mPelvis", "mTorso", "mChest", "mNeck", "mHead",
"mHipLeft", "mHipRight", "mKneeLeft", "mKneeRight",
"mAnkleLeft", "mAnkleRight", "mFootLeft", "mFootRight",
"mToeLeft", "mToeRight",
"mCollarLeft", "mCollarRight", "mShoulderLeft", "mShoulderRight",
"mElbowLeft", "mElbowRight", "mWristLeft", "mWristRight",
"mHandLeft", "mHandRight",
// Finger links
"mThumbLeft", "mThumbLeft01", "mThumbLeft02",
"mIndexLeft", "mIndexLeft01", "mIndexLeft02",
"mMiddleLeft", "mMiddleLeft01", "mMiddleLeft02",
"mRingLeft", "mRingLeft01", "mRingLeft02",
"mPinkyLeft", "mPinkyLeft01", "mPinkyLeft02",
// Finger rechts
"mThumbRight", "mThumbRight01", "mThumbRight02",
"mIndexRight", "mIndexRight01", "mIndexRight02",
"mMiddleRight", "mMiddleRight01", "mMiddleRight02",
"mRingRight", "mRingRight01", "mRingRight02",
"mPinkyRight", "mPinkyRight01", "mPinkyRight02",
// Zusätzliche Bento-Gelenke
"mEyeLeft", "mEyeRight", "mJaw",
"mTail01", "mTail02", "mTail03",
"mEarLeft", "mEarRight",
"mWingLeft", "mWingRight"
];
// Aktuelle Einstellungen
integer current_joint_index = 0;
rotation current_rotation = ZERO_ROTATION;
vector current_position = <0,0,0>;
key avatar_id = NULL_KEY;
// Hilfsfunktion zum Anwenden der Animation
update_animation()
{
if(avatar_id == NULL_KEY) return;
string joint = llList2String(BENTO_JOINTS, current_joint_index);
// Setze Rotation und Position für das aktuelle Prim (Root oder Link)
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROT_LOCAL, current_rotation, PRIM_POSITION, current_position]);
llSetText("Joint: " + joint + "\nRot: " + (string)llRound(llRot2Angle(current_rotation) * RAD_TO_DEG) + "°\nPos: " + (string)current_position, <1,1,1>, 1.0);
llSetText("Joint: " + joint + "\nRot: " + (string)llRound(llRot2Angle(current_rotation) * RAD_TO_DEG) + "°\nPos: " + (string)current_position, <1,1,1>, 1.0);
}
default
{
state_entry()
{
llOwnerSay("Bento Avatar Tester gestartet");
llOwnerSay("Befehle:");
llOwnerSay("/1 [jointname] - Wähle Gelenk (z.B. '/1 mHead')");
llOwnerSay("/1 next - Nächstes Gelenk");
llOwnerSay("/1 prev - Vorheriges Gelenk");
llOwnerSay("/1 list - Zeige alle Gelenke");
llOwnerSay("/1 rot X Y Z - Rotation in Grad (z.B. '/1 rot 0 90 0')");
llOwnerSay("/1 pos X Y Z - Position in Metern");
llOwnerSay("/1 reset - Setze Gelenk zurück");
llOwnerSay("/1 clear - Lösche alle Overrides");
llListen(1, "", llGetOwner(), "");
// Setze Text
llSetText("Bento Tester\nWarte auf Avatar...", <1,1,0>, 1.0);
}
on_rez(integer param)
{
llResetScript();
}
touch_start(integer total_number)
{
avatar_id = llDetectedKey(0);
llOwnerSay("Avatar erkannt: " + llKey2Name(avatar_id));
update_animation();
}
listen(integer channel, string name, key id, string message)
{
list parts = llParseString2List(message, [" "], []);
string cmd = llList2String(parts, 0);
if(cmd == "next")
{
current_joint_index = (current_joint_index + 1) % llGetListLength(BENTO_JOINTS);
current_rotation = ZERO_ROTATION;
current_position = ZERO_VECTOR;
update_animation();
llOwnerSay("Aktuelles Gelenk: " + llList2String(BENTO_JOINTS, current_joint_index));
}
else if(cmd == "prev")
{
current_joint_index = (current_joint_index - 1 + llGetListLength(BENTO_JOINTS)) % llGetListLength(BENTO_JOINTS);
current_rotation = ZERO_ROTATION;
current_position = ZERO_VECTOR;
update_animation();
llOwnerSay("Aktuelles Gelenk: " + llList2String(BENTO_JOINTS, current_joint_index));
}
else if(cmd == "list")
{
llOwnerSay("Verfügbare Gelenke:");
integer i;
for(i = 0; i < llGetListLength(BENTO_JOINTS); i++)
{
llOwnerSay(" " + (string)i + ": " + llList2String(BENTO_JOINTS, i));
}
}
else if(cmd == "rot")
{
if(llGetListLength(parts) >= 4)
{
float x = (float)llList2String(parts, 1) * DEG_TO_RAD;
float y = (float)llList2String(parts, 2) * DEG_TO_RAD;
float z = (float)llList2String(parts, 3) * DEG_TO_RAD;
// Konvertiere zu Quaternion (Reihenfolge: Z, Y, X für Euler)
current_rotation = llEuler2Rot(<x, y, z>);
update_animation();
llOwnerSay("Rotation gesetzt auf: " + llList2String(parts, 1) + "° " +
llList2String(parts, 2) + "° " + llList2String(parts, 3) + "°");
}
}
else if(cmd == "pos")
{
if(llGetListLength(parts) >= 4)
{
float x = (float)llList2String(parts, 1);
float y = (float)llList2String(parts, 2);
float z = (float)llList2String(parts, 3);
current_position = <x, y, z>;
update_animation();
llOwnerSay("Position gesetzt auf: " + (string)current_position);
}
}
else if(cmd == "reset")
{
current_rotation = ZERO_ROTATION;
current_position = ZERO_VECTOR;
update_animation();
llOwnerSay("Gelenk zurückgesetzt");
}
else if(cmd == "clear")
{
// Setze Rotation und Position zurück
current_rotation = ZERO_ROTATION;
current_position = ZERO_VECTOR;
update_animation();
llOwnerSay("Alle Gelenk-Positionen zurückgesetzt");
}
else if(cmd == "help")
{
llOwnerSay("Befehle:");
llOwnerSay("/1 [jointname] - Wähle Gelenk (z.B. '/1 mHead')");
llOwnerSay("/1 next - Nächstes Gelenk");
llOwnerSay("/1 prev - Vorheriges Gelenk");
llOwnerSay("/1 list - Zeige alle Gelenke");
llOwnerSay("/1 rot X Y Z - Rotation in Grad");
llOwnerSay("/1 pos X Y Z - Position in Metern");
llOwnerSay("/1 reset - Setze Gelenk zurück");
llOwnerSay("/1 clear - Lösche alle Overrides");
}
else
{
// Versuche Gelenkname direkt zu setzen
integer index = llListFindList(BENTO_JOINTS, [cmd]);
if(index != -1)
{
current_joint_index = index;
current_rotation = ZERO_ROTATION;
current_position = ZERO_VECTOR;
update_animation();
llOwnerSay("Gelenk ausgewählt: " + cmd);
}
else
{
llOwnerSay("Unbekannter Befehl. Tippe '/1 help' für Hilfe.");
}
}
}
}
Verwendung
1. Skript in ein beliebiges Prim legen (z.B. ein HUD oder ein Objekt in der Hand)
2. Avatar auswählen: Klicke das Objekt an, während du den zu testenden Avatar trägst
3. Steuerung über Chat-Befehle (Channel 1):
- `/1 next` - Nächstes Gelenk
- `/1 prev` - Vorheriges Gelenk
- `/1 list` - Alle verfügbaren Gelenke anzeigen
- `/1 [Gelenkname]` - Bestimmtes Gelenk auswählen (z.B. `/1 mHead`)
- `/1 rot X Y Z` - Rotation in Grad setzen (z.B. `/1 rot 0 45 0`)
- `/1 pos X Y Z` - Position in Metern setzen (Offset)
- `/1 reset` - Aktuelles Gelenk zurücksetzen
- `/1 clear` - Alle Overrides löschen
Wichtige Hinweise
- Das Skript verwendet **Prim Property Overrides**, um die Gelenke zu bewegen
- Der Avatar muss **Bento-kompatibel** sein
- Einige Gelenke funktionieren nur, wenn der Avatar sie tatsächlich besitzt
- Die Rotation wird in **Grad** angegeben (nicht Radianten)
- Das Skript zeigt immer das aktuell ausgewählte Gelenk und dessen Werte als HUD-Text an
Das Skript ist ideal zum Testen von Bento-Rigging und Animationen!
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.


![[-]](https://www.gridtalk.de/images/collapse.png)