logo
Homepage-Sicherheit

Willkommen Gast! Um alle Funktionen zu aktivieren müssen Sie sich Anmelden oder Registrieren.

Mitteilung

Icon
Error

Einloggen


Teilen
Optionen
Ansicht
Gehe zum aktuellsten Beitrag Gehe zum letzten Ungelesenen
Offline MartinRJ Fayray  
#1 Geschrieben : Sonntag, 1. November 2015 19:11:41(UTC)
MartinRJ Fayray

Rang: Ehrenmitglied

Ansehen:

Mitglied seit: 05.09.2014(UTC)
Beiträge: 90
Germany
Wohnort: Tulln und Rostock

Dankte: 6 mal(e)
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

Bearbeitet vom Benutzer Sonntag, 1. November 2015 19:20:26(UTC)  | Grund: Nicht angegeben

It is the mark of an educated mind to be able to entertain a thought without accepting it.
Rss Feed  Atom Feed
Benutzer, die gerade dieses Thema lesen
OceanSpiders 2.0
Das Forum wechseln  
Du kannst keine neue Themen in diesem Forum eröffnen.
Du kannst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge nicht löschen.
Du darfst deine Beiträge nicht editieren.
Du kannst keine Umfragen in diesem Forum erstellen.
Du kannst nicht an Umfragen teilnehmen.

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

Datenschutzrichtlinie
Haftungsausschluss
Impressum
Datenschutzerklärung
AGB, ToS
Kontakt