• Bitte schaltet eure Ad Blocker aus. SLinfo kann nur betrieben werden, wenn es durch Werbung Einnahmen erzielt. Vielen Dank!!
  • Wir freuen uns, wenn du dich in unserem Forum anmeldest. Bitte beachte, dass die Freigabe per Hand durchgeführt wird (Schutz vor Spammer). Damit kann die Freigabe bis zu 24 Stunden dauern.
  • Wir verwenden Cookies, um Inhalte und Anzeigen zu personalisieren, Funktionen für soziale Medien anbieten zu können und die Zugriffe auf unsere Website zu analysieren. Sie geben Einwilligung zu unseren Cookies, wenn Sie unsere Webseite weiterhin nutzen.

Avatare auf Parzelle

Shirley Iuga

Forumsgott/göttin
Das geht nur mit mehreren verteilten Sensoren und einer kleinen "Datenbank".
Ein Sensor kann eben leider nur die 16 nähesten Avas scannen. D.h. je nach Anzahl der Avas auf der Parzelle brauch man eben 3 oder 4 Sensoren um alle erfassen zu können.

D.h. du machst eben mehrere Objekte mit sowas:

PHP:
default
{
    state_entry()
    {
        llSensorRepeat("",NULL_KEY,AGENT,96.0,PI,5.0);
        //sucht alle 5 Sekunden nach Avas. Muss man noch 
        //anpassen an Parzellengröße und Suchwinkel.
    }
    sensor(integer total_number)
    {
        integer i;
        for (i=0;i<total_number;i++)
        {
            llRegionSay(-5,llDetectedName(i));
            //sagt alle erkannten Namen auf channel -5
        }
    }

}
und man braucht einen zentralen "Server" irgendwo, der die Inputs verarbeitet

PHP:
list AvasDetected;
default
{
    state_entry()
    {
        llListen(-5,"Sensordings",NULL_KEY,"");
        llSetTimerEvent(60.0);
    }

    listen(integer channel, string name, key id, string message)
    {
        if (llListFindList(AvasDetected,[message]) != -1)
        {
            AvasDetected += [message];
            //falls erkannter name nicht in Liste ist:
            //Name in Liste kopieren
        }
    }
    timer()
    {
        //Namen in Liste zählen und auswerten und Liste leeren.
        integer k = llGetListLength(AvasDetected);
        llSetText("gezählte Avas: " + (string) k,<1,1,1>,1.0);
        AvasDetected = [];
    }

}
Keine Ahnung obs Funktioniert (und erst recht keine Garantie...) aber so ungefähr müsste es gehen.
 
Vermutlich hilft die Antwort nicht wirklich, gibt aber die Richtung an:

Der Inprudence Viewer hat in der Minimap eine Funktion und zeigt die Avas die auf einer Parzielle ist an.

Lurch
 

Daemonika Nightfire

Forumsgott/göttin
Also fuer die ganze Sim, faellt mir auch nur das ein:
Code:
//Tell the owner how many avatars are in the region on touch
[URL="http://wiki.secondlife.com/index.php?title=default"]default[/URL]
{
    [URL="http://wiki.secondlife.com/index.php?title=touch_start"]touch_start[/URL]([URL="http://wiki.secondlife.com/index.php?title=integer"]integer[/URL] count)
    {
        [URL="http://wiki.secondlife.com/index.php?title=llOwnerSay"]llOwnerSay[/URL](([URL="http://wiki.secondlife.com/index.php?title=string"]string[/URL])[URL="http://wiki.secondlife.com/index.php?title=llGetRegionAgentCount"]llGetRegionAgentCount[/URL]());
    }
}
Quelle: LlGetRegionAgentCount - Second Life Wiki

Aber es auf eine Parzelle beschraenken, da wuesste ich auch nur den handelsueblichen Radar.
Der zaehlt aber auch nur bis 16 und is dann ueberfordert.

LG
Dae
 

Jasmin Ewing

Aktiver Nutzer
Kleines Gedankenspiel:

soweit mir bekannt ist betrifft die 16-Personen-Beschränkung den einzelnen Sensor, wenn man nun mehrere Sensoren unterschiedlicher Reichweite macht und die Ergebnisse über Listen verwaltet müßte man um diese Beschränkung herumschiffen können ABER man erkauft sich das mit ziemlich viel Lag denke ich.

nur einfach mal zum Nachdenken


LG Jasmin


P.S. es gab meiner Ansicht nach noch eine Prüfmöglichkeit in der Art "AvatarOnSameParcel" oder so ähnlich - damit könnte man die die nicht darauf sind ausschließen.
 
Die Lösung für die Beschränkung der 16 gescannten Avatare gab Shirley schon. Man verteilt mehrere Sensoren. Wird als ein Avatar nicht erkannt, weil es der 17. z.b. ist, dann wird er dafür von einem dahinter liegenden Sensor erkannt. Die Reihenfolge der Erkennung geht immer nach der Entfernung, den nähesten avatar zuerst.

Fehlt nur noch die Prüfung, ob sich der erkannte Avatar auf deiner Parzelle befindet, denn der Sensor kennt keine Parzellen Grenzen. Das macht der Befehl llOverMyLand(key id); Das gibt TRUE ider FALSE zurück.
Nicht vergessen, daß das Object mit deinem Script auf Gruppe übertragen werden muss, falls sich das Land im Gruppenbesitz befindet.
 

Jasmin Ewing

Aktiver Nutzer
Da hast du recht, Marc. Aber wenn ich 10 Sensoren laufen lasse (auch dann wenn diese nur alle 10 Minuten scannen) ist die Belastung 10mal so hoch ... das meinte ich mit dem "erkaufen".
 
Da hast du recht, Marc. Aber wenn ich 10 Sensoren laufen lasse (auch dann wenn diese nur alle 10 Minuten scannen) ist die Belastung 10mal so hoch ... das meinte ich mit dem "erkaufen".
Da hast du vollkommen recht. Man soll natürlich nur soviel Sensoren hin setzen wie unbedingt nötig für den Zweck. Aber da können wir keinen Rat hier geben, weil das ja von der Größe der Parzelle und der Anzahl der normalerweise anwesenden Avatare abhängt.

Eventuell kann noch eine andere Technik sinnvoller sein abhängig von den Gegebenheiten. Und zwar nimmt man ein unsichtbares Mega Prim in der Größe der Parzelle. Auf dieses wendet man den Befehl llVolumeDetect(TRUE); an. Dieser Befehl macht das Prim Phantom, aber im Gegensatz zur normalen Phantom Eigenschaft erkennt es nach wie vor Kollisionen im Script. So kann man dann das Prim von unten nach oben bewegen lassen und die Avatare werden per Kollision erkannt.
Auch diese Technuk soll man natürlich zur Vermeidung von Lag nicht häufiger machen als unbedingt erforderlich.
 
Hmmmm also wenn z. b. 17 Leute genau in der gleichen Range stehen würden, dann ist es technisch unmöglich mit Sensor den Fall abzudecken, es sei man stell mehr als einen Sensor auf?

Collision-Idee finde ich irgendwie besser, solang man einen sleep() oder so reinhaut.
 

Daemonika Nightfire

Forumsgott/göttin
Mit collisionen is net zu spassen.
Stell dir mal 17 Avatare auf einem Megaprim vor jeweils die ohne sich zu bewegen etwa 4x pro secunde (optische beobachtung) einen collisions-Event ausloesen.
Ob das nun weniger lagt, glaube ich nicht.
 

Daemonika Nightfire

Forumsgott/göttin
Ein llSleep haelt dein Script fuer die "angegebene zeit" an.
Wenn die sim aber laggy ist, dauert es schon mal erheblich laenger.
Da werden je nach lag, aus 5 secunden schon mal 30 oder mehr.

Wenn dann wuerd ich ehr einen timer an stelle eines sleep empfehlen.
 

Simon Illyar

Freund/in des Forums
1.tens wird ein timer auch von Lag beeinflusst.
2.tens wird der collisions-event nicht nur 4x pro sekunde ausgelösst, das bewegt sich dann schon im hunderstel wenn nicht sogar tausendstel sekunden bereich.
3.tens macht wärend des sleeps das script auch nichts anderes als schlafen, sobald der sleep aufhört rechnet es weiter, wenn es fertig ist wird der nächste event ausgelöst. Also der nächste sleep.
Bedeutet, alle paar sekunden schießt der lag in die höhe.
4.tens werden die reinen collison events bei llVolumeDetect, sowieso nicht ausgelöst.

Also timer und sleep idiotisch.
Arbeit mit collision_start und collision_end möglich, was selbst wenn der collison event ausgelöst werden würde, die besser Wahl wäre statt sich da was mit timer zusammen zu würfeln.


Gruß Simon
 

Daemonika Nightfire

Forumsgott/göttin
@ Simon

Mit meiner schaetzung ohne die nur auf optischer wahrnehmung basierte lag ich gar nicht so daneben.
Ich wuerde sagen du hast den Collisions-wert weit ueberschaetzt.
Tatsaechlich wird ein Collisions Event wirklich nur zwischen 3 und 5 mal pro secunde ausgefuehrt.

Dazu hab ich mal einen kleinen Test geschrieben.
Script:
Code:
[COLOR=DarkGreen]integer[/COLOR] unixtime;
[COLOR=DarkGreen]integer[/COLOR] durchlauf; [COLOR=Orange]// na, komt dir das bekannt vor? :P[/COLOR]
default
{
    [COLOR=RoyalBlue]collision_start[/COLOR]([COLOR=DarkGreen]integer[/COLOR] num_detected)
    {
        unixtime = [COLOR=Red]llGetUnixTime()[/COLOR];
        [COLOR=Red]llSay[/COLOR](0, "collision_start");
    }
    [COLOR=RoyalBlue]collision[/COLOR]([COLOR=DarkGreen]integer[/COLOR] num_detected)
    {
        durchlauf += 1;
        [COLOR=Blue]if[/COLOR](([COLOR=Red]llGetUnixTime()[/COLOR] - unixtime) < 2)
        {
            [COLOR=Red]llSay[/COLOR](0, ([COLOR=DarkGreen]string[/COLOR])durchlauf);
        }
    }
    [COLOR=RoyalBlue]collision_end[/COLOR]([COLOR=DarkGreen]integer[/COLOR] num_detected)
    {
        durchlauf = 0;
        [COLOR=Red]llSay[/COLOR](0, "collision_end");
    }
}
Ich habs auf 2 secunden getestet um aussagekraeftigere werte zu bekommen

Ergebniss:
[12:54] Object: collision_start
[12:54] Object: 1
[12:54] Object: 2
[12:54] Object: 3
[12:54] Object: 4
[12:54] Object: 5
[12:54] Object: 6
[12:54] Object: 7
[12:54] Object: 8
[12:54] Object: collision_end
[12:54] Object: collision_start
[12:54] Object: 1
[12:54] Object: 2
[12:54] Object: 3
[12:54] Object: 4
[12:54] Object: 5
[12:54] Object: 6
[12:54] Object: 7
[12:54] Object: 8
[12:54] Object: collision_end
Die ergebnisse waren recht unterschiedlich und beliefen sich auf ueberwiegend 8 bis maximal 10 mal pro 2 secunden.
Das dort "Object: collision_end" steht, liegt ganz einfach dan das es nichts mehr von sich gab und ich runter ging.

LG
Dae
 

Simon Illyar

Freund/in des Forums
Und wenn wir mal den ganzen schwachsinn rausnehmen, der das script verlangsamt und uns auf das wesendliche beschränken.

Code:
default
{
    collision(integer total_number)
    {
        llOwnerSay(llGetTimestamp());
    }
}

Kommen wir auf etwa 7 Ausgaben pro Sekunde.

[13:13] Object: 2010-10-22T20:13:55.847840Z
[13:13] Object: 2010-10-22T20:13:55.989985Z
[13:13] Object: 2010-10-22T20:13:56.130173Z
[13:13] Object: 2010-10-22T20:13:56.269902Z
[13:13] Object: 2010-10-22T20:13:56.406613Z
[13:13] Object: 2010-10-22T20:13:56.556248Z
[13:13] Object: 2010-10-22T20:13:56.695020Z
[13:13] Object: 2010-10-22T20:13:56.831383Z
[13:13] Object: 2010-10-22T20:13:56.967859Z
[13:13] Object: 2010-10-22T20:13:57.099335Z
[13:13] Object: 2010-10-22T20:13:57.239362Z
[13:13] Object: 2010-10-22T20:13:57.381742Z
[13:13] Object: 2010-10-22T20:13:57.524879Z
[13:13] Object: 2010-10-22T20:13:57.660415Z
[13:13] Object: 2010-10-22T20:13:57.796124Z
[13:13] Object: 2010-10-22T20:13:57.933622Z
[13:13] Object: 2010-10-22T20:13:58.072662Z


Aber immer noch zu grob.

Also ein prim als Platte.
Und ein prim den ich physikalisch drauf fallen lasse.

In der Platte.

Code:
integer Anzahl;


default
{
    collision(integer total_number)
    {
        Anzahl = -~Anzahl;
    }
    collision_end(integer number)
    {
        llOwnerSay((string)Anzahl);
    }
}

In dem Physikalischen Prim

Code:
integer Anzahl;


default
{
    collision_start(integer total_number)
    {
        llOwnerSay(llGetTimestamp());
    }
    collision_end(integer number)
    {
        llOwnerSay(llGetTimestamp());
    }
}

Ausgabe:

[13:23] Object: 2010-10-22T20:23:26.683473Z
[13:23] Object: 2010-10-22T20:23:26.948921Z
[13:23] Object: 12

Das sind 12 Treffer in 0.3 sekunden.
Das sind 40 Treffer pro Sekunde.

oder 4 pro Zentel.

Da liege ich durchaus noch weit weg von dem hunderstel oder sogar tausendstel bereich, aber 3 oder 5 mal pro sekunde ist auch etwas wenig.


Gruß Simon

Nachtrag wegen einem Fehler:
Es sind doch nur 4 Treffer in 0.3 sekunden
Immerhin noch 12 pro sekunde.
 

Aktive User in diesem Thread

Oben Unten