logo

Willkommen Gast! Um alle Funktionen zu aktivieren müssen Sie sich Anmelden.Neue Registrierungen sind deaktiviert.

Mitteilung

Icon
Error

Einloggen


Beitrag melden
Geschrieben von: MartinRJ Fayray Offline Geschrieben Sonntag, 1. November 2015 19:11:41(UTC)
Das folgende Skript ist für eine vollautomatische Turret gedacht.
Das Skript muss ins Root-Prim. In diesem Fall (siehe Bild im Anhang) besteht die Turret aus drei Teilen:
  • einem unbeweglichen Unterbau (in dieses Prim kommt das Skript),
  • einem Geschützturm der sich um 360° dreht,
  • und der Kanone, die sich auf und ab bewegt.


Ganz oben im Skript, kann man diverse Anpassungen machen (etwa für die Ausgangsstellung).

Das Geschütz feuert automatisch auf alle Avatare die sich ihm nähern.

Code:

//Offsets und Werte der Child-Prims (Aufbau):
integer iLinknumberPart1 = 2;
vector vOffsetAvatar = <0.0, 0.0, 0.5>; //Avatar-Offset.
integer iLinknumberPart2 = 3;
float fWinkelMinimum = -30.0; //° Grad.
float fWinkelMaximum = 45.0; //° Grad.
rotation rRotationDefault1 = <0.0, 0.0, 0.0, 0.0>; //Ausgangsstellung
rotation rRotationDefault2 = <0.0, 0.0, 0.0, 0.0>;


float fSCAN_INTERVAL = 0.2; //Scannt alle 0.2 Sekunden nach dem nächsten Avatar.
float fSCAN_RANGE = 5.0; //Sucht im Radius von 10 Metern nach Avataren.
key scan()
{ //Scannt nach dem nächsten Avatar und gibt dessen UUID zurück, andernfalls NULL_KEY.
    integer iCounter = 0;
    vector vPosition;
    float fDistance;
    key kAvatar;
    key kNearestAvatar = NULL_KEY;
    float fNearestAvatarsDistance = fSCAN_RANGE; //Mit fSCAN_RANGE initialisieren für den Vergleich der Distanz.
    list lAvatarsInRegion = llGetAgentList(AGENT_LIST_REGION, []);
    integer iNumOfAvatars = llGetListLength(lAvatarsInRegion);
    for (iCounter = 0; iCounter < iNumOfAvatars; iCounter++)
    {
        kAvatar = llList2Key(lAvatarsInRegion, iCounter);
        vPosition = llList2Vector(llGetObjectDetails(kAvatar, [OBJECT_POS]), 0);
        fDistance = llVecDist(llGetPos(), vPosition); //Distanz jedes Avatars.
        if (fDistance < fNearestAvatarsDistance)
        { //Dieser Avatar ist näher als alle anderen.
            kNearestAvatar = kAvatar;
            fNearestAvatarsDistance = fDistance; //Distanz und Avatar speichern.
        }
    }
    return kNearestAvatar;
}

start_scan()
{ //Starte Scan.
    llSetTimerEvent(fSCAN_INTERVAL);
}

stop_scan()
{ //Stoppe Scan.
    llSetTimerEvent(0.0);
}

integer iListIndexPos = 0;
integer iListIndexRot = 1;
list lGetRegionCoordsOfLinkPrim(integer iLinknumber)
{ //Erzeugt eine Liste mit Regions-Koordinaten und -Rotation des Childprims "iLinknumber".
    list lReturn = [0,0]; //Liste für die Rückgabewerte.
    //Lese lokale Koordinaten des Childprims aus.
    vector vPosCHILDPRIM = llList2Vector(llGetLinkPrimitiveParams(iLinknumber, [PRIM_POS_LOCAL]), 0);
    rotation rRotCHILDPRIM = llList2Rot(llGetLinkPrimitiveParams(iLinknumber, [PRIM_ROT_LOCAL]), 0);

    //Fall beachten, wenn iLinknumber das RootPrim ist.
    if (iLinknumber <= 1)
    {
        vPosCHILDPRIM = ZERO_VECTOR;
        rRotCHILDPRIM = ZERO_ROTATION;
    }

    //Position und Rotation von Root-Prim auslesen.
    vector vPosROOT = llGetRootPosition();
    rotation rRotROOT = llGetRootRotation();

    //Konvertieren.
    vector vRegionPosCHILDPRIM = vPosCHILDPRIM * rRotROOT + vPosROOT;
    rotation rRegionRotCHILDPRIM = rRotCHILDPRIM * rRotROOT;

    //Rückgabeliste füllen und zurückgeben.
    lReturn = llListReplaceList(lReturn, [vRegionPosCHILDPRIM], iListIndexPos, iListIndexPos);
    lReturn = llListReplaceList(lReturn, [rRegionRotCHILDPRIM], iListIndexRot, iListIndexRot);

    return lReturn;
}

aim(key kTarget)
{ //Ziele/schieße auf den Avatar kTarget.
    vector vPosition;
    vPosition = llList2Vector(llGetObjectDetails(kTarget, [OBJECT_POS]), 0) + vOffsetAvatar;
    //Debug: //llSetText(llKey2Name(kTarget), <1.0, 1.0, 1.0>, 1.0);

    //Childprim 1:

    list lCoordsChildprim1 = lGetRegionCoordsOfLinkPrim(iLinknumberPart1); //Regionskoordinaten der Childprims ermitteln.
    vector vRegionPosChildprim1 = llList2Vector(lCoordsChildprim1, iListIndexPos);
    rotation rRegionRotChildprim1 = llList2Rot(lCoordsChildprim1, iListIndexRot);
    //Debug: //llOwnerSay("Region coords: " + (string)vRegionPosChildprim1 + " / " + (string) rRegionRotChildprim1);

    //Target-Z-Position an die des Childprims anpassen:
    vector vPosHelper = <vPosition.x, vPosition.y, vRegionPosChildprim1.z>;
    //Neue Rotation von Childprim1 ausrechnen:
    rotation rRotChildprim1 = llRotBetween( <1.0,0.0,0.0>, llVecNorm( vPosHelper - vRegionPosChildprim1 ) );
    //Debug: //llOwnerSay((string)rRotChildprim1);

    llSetLinkPrimitiveParamsFast(iLinknumberPart1, [PRIM_ROT_LOCAL, rRotChildprim1]);


    //Childprim 2:

    list lCoordsChildprim2 = lGetRegionCoordsOfLinkPrim(iLinknumberPart2); //Regionskoordinaten der Childprims ermitteln.
    vector vRegionPosChildprim2 = llList2Vector(lCoordsChildprim2, iListIndexPos);
    rotation rRegionRotChildprim2 = llList2Rot(lCoordsChildprim2, iListIndexRot);
    //Debug: //llOwnerSay("Region coords: " + (string)vRegionPosChildprim2 + " / " + (string) rRegionRotChildprim2);

    //Target auf X-Achse projizieren für die weitere Berechnung:
    vector vPosHelper_PointA1 = <vRegionPosChildprim2.x + llVecDist(<vPosition.x, vPosition.y, vRegionPosChildprim2.z>, vRegionPosChildprim2), vRegionPosChildprim2.y, vRegionPosChildprim2.z>;
    vector vPosHelper_PointB1 = <vPosHelper_PointA1.x, vPosHelper_PointA1.y, vPosition.z>;
    //Z-Winkel zwischen Childprim2 und Target ausrechnen:
    vector vPosHelper_A = vPosHelper_PointA1 - vRegionPosChildprim2;
    vector vPosHelper_B = vPosHelper_PointB1 - vRegionPosChildprim2;
    float fAngle = llAtan2(llVecMag(vPosHelper_A % vPosHelper_B), vPosHelper_A * vPosHelper_B);
    //Debug: //llOwnerSay((string)llAxisAngle2Rot(<1.0, 0.0, 0.0>, fAngle));return;

    //Herausfinden, ob der Winkel positiv oder negativ ist:
    integer iPositiveAngle = TRUE;
    if (vPosition.z < vRegionPosChildprim2.z)
    { //Winkel ist negativ.
        iPositiveAngle = FALSE;
    }

    //Winkel umrechnen:
    vector vDegrees = llRot2Euler(llAxisAngle2Rot(<-1.0, 0.0, 0.0>, fAngle)) * RAD_TO_DEG;
    float fDegrees = vDegrees.x;
    if (!iPositiveAngle)
    {
        fDegrees = -fDegrees;
    }
    //Minimum und Maximum anwenden.
    if (fDegrees < fWinkelMinimum)
    {
        fDegrees = fWinkelMinimum;
    }
    if (fDegrees > fWinkelMaximum)
    {
        fDegrees = fWinkelMaximum;
    }
    //Debug: //llOwnerSay((string)fDegrees);

    //Target-Z-Position an die des Childprims anpassen:
    vPosHelper = <vPosition.x, vPosition.y, vRegionPosChildprim2.z>;
    //Neue Rotation von Childprim2 ausrechnen:
    rotation rRotChildprim2 = llRotBetween( <1.0,0.0,0.0>, llVecNorm( vPosHelper - vRegionPosChildprim2 ) );
    //Debug: //llOwnerSay((string)rRotChildprim2);

    llSetLinkPrimitiveParamsFast(iLinknumberPart2, [PRIM_ROT_LOCAL, llEuler2Rot(<0.0, fDegrees, 0.0>*DEG_TO_RAD)*rRotChildprim2]);
}

stop_aim()
{ //Kein Avatar in Reichweite, höre auf zu zielen.
    //Debug: //llSetText("Niemand hier", <1.0, 1.0, 1.0>, 1.0);
    llSetLinkPrimitiveParamsFast(iLinknumberPart1, [PRIM_ROT_LOCAL, rRotationDefault1]);
    llSetLinkPrimitiveParamsFast(iLinknumberPart2, [PRIM_ROT_LOCAL, rRotationDefault2]);   
}

fire()
{
    llWhisper(0, "Bam!");
}
default
{
    state_entry()
    {
        start_scan();
    }

    timer()
    {
        key kAvatar = scan();
        if (kAvatar != NULL_KEY)
        { //Avatar gefunden.
            aim(kAvatar); //Zielen
            fire(); //Schießen.
        }
        else
        {
            stop_aim();
        }
    }
}



Turret Beispiel
Geben Sie den Meldetext hier ein.
Fett Kursiv Unterstrichen   Hervorheben Zitat Sprachauswahl für Syntax Highlighting Bild einfügen Link einfügen   Unsortierte Liste Sortierte Liste   Linksbündig Zentriert Rechtsbündig   Herausrücken Einrücken   Weitere BBCodes
Schriftfarbe: Schriftgröße:
Melden Abbruch

Powered by YAF.NET | YAF.NET © 2003-2018, Yet Another Forum.NET
Diese Seite wurde in 0.025 Sekunden generiert.

Datenschutzrichtlinie
Haftungsausschluss
Impressum
Datenschutzerklärung
AGB, ToS
Kontakt