Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Einfache, leicht erweiterbare NPC Steuerung
#1
Hallöchen!

Ich wollte auf einer Sim ein NPC als Maskottchen umherwandern lassen.
Dazu habe ich mir ein einfaches System mit drei kleinen Scripten ausgedacht. Da es auch andere vielleicht gebrauchen können,
poste ich es frech hierher ^^

Das erste Script kommt in den NPC (bzw. in ein Objekt was er trägt).
Er wandert dann zum ersten Checkpoint, wo er sein nächstes Ziel abfragt.

Das zweite Script kommt in die Checkpoints, die an alle Abzweigungen gebaut werden. Es enthält alle UUIDs der erreichbaren Nachbar – Checkpoints
und wählt per Zufall einen davon aus. Ich habe mir dafür einen kleinen Phantomwürfel gerezzt, den ich wg der
begrenzten Reichweite (um Überschneidungen in Räumen zu vermeiden "hört" der NPC nur 1,5m weit auf Befehle) auf halber Avatarhöhe schweben lasse.

Und das dritte Script kommt in ein Schalterobjekt um die Checkpoints simweit sichtbar/unsichtbar zu schalten.






Das Script für den NPC:
Code:
// NPC Steuerungssystem
// MoniTill 8.13 V1
// Lizenz: Gemeinfrei (Public Domain)

// Script für Objekt am Avatar/NPC



key zielchkp = "0c3a6a5b-df1f-4d43-8370-775cfc1fbcda"; // Den ersten Checkpoint nach dem Rezzen ansteuern
//  Diese Zeile muss angepasst werden. Der Rest nur bei Bedarf


integer NPCkanal = 15432; // Der Kanal für das System. Falls NPCs unterschiedliche Wege nutzen sollen, einfach versch. Kanäle verw.
vector ziel;
vector altziel;
float maxZeit = 60 ; //Wenn in 60 Sek. noch nicht am Ziel, wird er wohl aufgehalten, also Teleport und fertig!^^
float startzeit;
integer fragenzaehler;      // Wenn er zurück soll, fragt er mehrmals (5x)nach.
                            // Falls dann immer noch der alte Checkpoint kommt,
                            // steckt er wohl in einer Sackgasse u. muss wirklich zurück


integer flag;

// Für die Verwendung in SL muss osNpcMoveToTarget u. osIsNpc entfernt u. osTeleportOwner ersetzt werden
// dann sollte es auch dort laufen.... glaube ich :O)..

default
{
    state_entry()
    {


        llSetStatus(STATUS_PHYSICS, TRUE);
      
        llSleep(10);
    llResetTime();
        list checkpointPOSstr = llGetObjectDetails(zielchkp,[OBJECT_POS]);
    ziel = llList2Vector(checkpointPOSstr,0);
  
  
    llSetTimerEvent(2.0);    
    llListen( NPCkanal, "", NULL_KEY, "" );
    }

    timer()
    {
    
    key  npc=llGetOwner();

    if (osIsNpc(npc) == TRUE)
    {
        //Wenn er als echter NPC unterwegs ist, gilt diese Zeile....
        osNpcMoveToTarget(npc,ziel, OS_NPC_NO_FLY) ;
    }
    else
    {
        //..und beim Test mit Viewer gilt diese.
        llMoveToTarget(ziel,0.05);    
        // Bei Verwendung in SL muss die "if/else" Schleife weg und nur der llMoveToTarget stehen bleiben
        
        
     }  


    if (llVecDist(ziel,llGetPos()) < 1.5)
    {
        flag= 1;
        llWhisper(NPCkanal,"*ziel*");
        llResetTime();
        startzeit=llGetTime();
    }
  
  
    if (startzeit +maxZeit < llGetTime() )
    {
        osTeleportOwner(ziel,ZERO_VECTOR);
        // Bei Verwendung in SL muss dieser Befehl ersetzt werden
    }
   }

  
  
  
   listen( integer channel, string name, key id, string msg)  
   {  
      list checkpointPOSstr = llGetObjectDetails(id,[OBJECT_POS]);
      vector checkpointPOS = llList2Vector(checkpointPOSstr,0);
      float distanz = llVecDist(checkpointPOS,llGetPos());
    
    
    
      if (flag == 1 && llGetSubString(msg, 0, 5)== "*gehe*" && distanz < 1.5)
      {
        vector msgz =(vector)llGetSubString(msg, 6, -1);
  
        if (msgz != altziel  || fragenzaehler > 4 )
        {
            //llWhisper(0,(string)fragenzaehler + (string)ziel+ (string)altziel);
            altziel = ziel;
            ziel = msgz;
            flag= 0;


            fragenzaehler = 0;
        }
        else
        {
            fragenzaehler += 1;
        }
  
      }  
  
   }
}




Das Script für die Checkpoints:
Code:
// NPC Steuerungssystem
// MoniTill 8.13 V1
// Lizenz: Gemeinfrei (Public Domain)

// Script für die Checkpoints



// Liste der anderen Checkpoints, die von diesem ohne Hindernisse erreichbar sind
list npcWeg = ["4f081952-f657-4e78-8b8b-f9633ae7729f","0c3a6a5b-df1f-4d43-8370-775cfc1fbcda"];
// Diese Zeile muss angepasst werden. Der Rest nur bei Bedarf


integer NPCkanal = 15432;  // Der Kanal für das System
integer i;
integer ii;
key npc;  

integer randInt(integer n)
{
      return (integer)llFrand(n + 1);
}

integer randIntBetween(integer min, integer max)
{
      return min + randInt(max - min);
}
      

default
{
    state_entry()
    {

        ii = llGetListLength(npcWeg);
    llListen( NPCkanal, "", NULL_KEY, "" );
    }

    
    listen( integer channel, string name, key id, string msg)  
    {

    if (msg == "ckptranson")
    {
        llSetAlpha(0.0, ALL_SIDES);
    }
  
    if (msg == "ckptransoff")
    {
        llSetAlpha(1.0, ALL_SIDES);
    }


    if (msg == "*ziel*")
    {
        i = randIntBetween(0, ii - 1);
        string checkpointPOSstr =llList2String( llGetObjectDetails(llList2String(npcWeg,i),[OBJECT_POS]),0);
        llWhisper(NPCkanal,"*gehe*"+checkpointPOSstr );
    }
   }
}





Das Script für den Schalter:
Code:
// NPC Steuerungssystem
// MoniTill 8.13 V1
// Lizenz: Gemeinfrei (Public Domain)

// Script für Schalter um die Checkpoints unsichtbar/sichtbar zu machen


integer NPCkanal = 15432; // Der Kanal für das System
integer ckptrans;



default
{
  


   touch_start(integer nummer)
   {
        if(ckptrans == 0)
        {
            llRegionSay(NPCkanal,"ckptranson");
        ckptrans = 1;
        }
        else
        {
            llRegionSay(NPCkanal,"ckptransoff");
        ckptrans = 0;
        }
   }
}
Zitieren


Nachrichten in diesem Thema
Einfache, leicht erweiterbare NPC Steuerung - von MoniTill - 14.08.2013, 13:38

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste