Welche Art von Lenkverhalten oder Logik kann ich verwenden, um Handys dazu zu bringen, andere zu umgeben?

10

Ich benutze die Wegfindung in meinem Spiel, um einen Mob zu einem anderen Spieler zu führen (um ihn zu verfolgen). Dies funktioniert, um sie über den Player zu bringen, aber ich möchte, dass sie kurz vor ihrem Ziel anhalten (die Auswahl des vorletzten Knotens funktioniert also einwandfrei).

Wenn jedoch mehrere Mobs das Handy verfolgen, stapeln sie sich manchmal "übereinander". Was ist der beste Weg, um dies zu vermeiden? Ich möchte die Mobs nicht als undurchsichtig und blockiert behandeln (weil sie es nicht sind, können Sie durch sie gehen), aber ich möchte, dass die Mobs einen Sinn für Struktur haben.

Beispiel:

Stellen Sie sich vor, jede Schlange führte sich zu mir und sollte "Setsuna" umgeben. Beachten Sie, wie beide Schlangen beschlossen haben, mich zu stechen? Dies ist keine strenge Anforderung. sogar leicht versetzt zu sein ist okay. Aber sie sollten Setsuna "umgeben".

Geben Sie hier die Bildbeschreibung ein

Vaughan Hilts
quelle
1
Ist das Stapeln nur am Bestimmungsort oder auch während des Transports ein Problem? Letzteres vermute ich.
SpartanDonut
Es ist das letztere, @SpartanDonut
Vaughan Hilts
@KromStern Ich habe ein Bild hinzugefügt, hoffe es hilft.
Vaughan Hilts

Antworten:

15

Geben Sie Ihren Agenten eine schwache "elektrostatische Aufladung", damit sie sich gegenseitig abstoßen, wie es das Coulombsche Gesetz vorsieht .

Der Einfachheit halber sollte angenommen werden, dass sich Mobs mit gleicher Stärke gegenseitig wegdrücken sollten, und es sollte ausreichen, eine Kraft zwischen jedem Paar von Mobs mit einer Größe aufzubringen some_constant / distance^2, wobei some_constanteine konfigurierbare Abstoßungsstärke und distanceder Abstand zwischen ihnen ist.

Die Abstoßungsstärken fallen dann mit dem Quadrat der Entfernung ab.

Nature of Code hat ein großartiges Beispiel (mit einer LiveDemo) hier . Es sieht aus wie das:

kombinierte folgen und getrennte Verhaltensweisen

Jedes Element gegeneinander abzugleichen ist eine O(n^2)Operation mit quadratischer Zeit ( ). Wenn Sie wirklich viele Agenten haben, möchten Sie möglicherweise die Kraftberechnungen mit einer Barnes-Hut-Näherung optimieren , die auf log-linear ( O(n log n)) reduziert wird, aber einen Quadtree erfordert .

Anko
quelle
Großartige Verbindung, Anko. Sehr geschätzt! Ich werde auf jeden Fall diese ganze Seite durchlesen müssen.
Vaughan Hilts
Starcraft (mindestens 1) macht etwas Ähnliches mit seinen fliegenden Einheiten. Aber es tut es nur, wenn sie aufhören, sich zu bewegen, dh wenn sie in Bewegung sind, klumpen sie übereinander (ignorieren sich gegenseitig völlig als Hindernisse), aber wenn sie aufhören, breiten sie sich alle aus dem aus, was so aussieht, als wäre es das lokales Zentrum eines regulären Bereichs (wahrscheinlich Quadrat / Kreis), der sie umfasst. Dies sieht nicht so hübsch aus wie das Beispiel in der Antwort, aber es
verbraucht
@ShivanDragon SC2 zeigt das gleiche Verhalten, alle konvergieren in einer Menschenmenge zum Ziel und bieten Platz für ein realistisches und ästhetisch ansprechendes Aussehen (damit ihre Teile nicht herumschneiden).
Kroltan
2
Eine Art abstoßende Kraft kann eine gute Idee sein, aber die Details sind schwierig. Ich habe mit diesen in einem raumbezogenen RTS experimentiert und empfehle, die Physik nicht zu genau zu verfolgen und sie lieber so zu modellieren, dass sie sich gut verhält. Einige Beobachtungen: 1) Da dies keine physikalische Simulation ist, würde ich die Kraft nur über kurze Entfernungen anwenden. 2) Dies kann nicht verhindern, dass sich endliche Körper überlappen. 3) Das harte Potential verursacht leicht numerische Fehler, wie z. B. Partikel, die mit hohen Geschwindigkeiten gebrochen werden. 4) Sobald Sie eine signifikante Anzahl von Partikeln haben und der Druck in der Mitte steigt, werden die Dinge hässlich.
CodesInChaos
1

Mein Ansatz ähnelt dem von @ Anko, basiert jedoch auf der Arbeit von Millington und Funge von Artificial Intelligence for Games .

So würde ein Trennungsverhalten aussehen, aber Sie müssen berücksichtigen, dass diese Geschwindigkeit mit der Geschwindigkeit des Agenten in seiner Aktualisierungsfunktion berechnet werden sollte.

public Vector3 GetSeparationVel (float threshold, float decayCoefficient)
{
    threshold = threshold * threshold;
    Vector3 separationVelocity = Vector3.Zero;
    for (int i = 0; i < enemies.Length; i++) {
        if (enemies[i] == this) {
            continue;
        }
        Vector3 direction = this.position - enemies[i].position;
        float distance = direction.LengthSquared();
        float strenght = 0.0f;
        if (distance < (threshold)) {
            strenght = Math.Min(decayCoefficient / distance, this.maxAccel);
            direction.Normalize();
            separationVelocity += strenght * direction;
        }
    }
}
Reefaktor
quelle