Wie man Hunderte von 'In-Game'-Charakteren am besten strukturiert / verwaltet

10

Ich habe in Unity ein einfaches RTS-Spiel gemacht, das Hunderte von Charakteren wie Crusader Kings 2 enthält. Zum Speichern wäre es am einfachsten, skriptfähige Objekte zu verwenden. Dies ist jedoch keine gute Lösung, da Sie zur Laufzeit keine neuen erstellen können.

Also habe ich eine C # -Klasse namens "Character" erstellt, die alle Daten enthält. Alles funktioniert gut, aber während das Spiel simuliert, werden ständig neue Charaktere erstellt und einige Charaktere getötet (wenn Ereignisse im Spiel auftreten). Während das Spiel kontinuierlich simuliert, werden Tausende von Charakteren erstellt. Ich habe eine einfache Überprüfung hinzugefügt, um sicherzustellen, dass ein Charakter "lebendig" ist, während er seine Funktion verarbeitet. Es hilft also der Leistung, aber ich kann "Charakter" nicht entfernen, wenn er / sie tot ist, da ich seine / ihre Informationen beim Erstellen des Stammbaums benötige.

Ist eine Liste der beste Weg, um Daten für mein Spiel zu speichern? Oder wird es Probleme geben, wenn 10000s eines Charakters erstellt wurden? Eine mögliche Lösung besteht darin, eine weitere Liste zu erstellen, sobald die Liste eine bestimmte Menge erreicht hat, und alle toten Zeichen darin zu verschieben.

paul p
quelle
9
Eine Sache, die ich in der Vergangenheit getan habe, als ich nach dem Ableben eine Teilmenge der Daten eines Charakters benötige, ist das Erstellen eines "Grabstein" -Objekts für diesen Charakter. Der Grabstein kann die Informationen enthalten, die ich später nachschlagen muss, aber er kann kleiner sein und weniger oft wiederholt werden, da keine ständige Simulation wie bei einem lebenden Charakter erforderlich ist.
DMGregory
2
Ist das Spiel wie CK2 oder geht es nur darum, viele Charaktere zu haben? Ich habe verstanden, dass das ganze Spiel wie CK2 ist. In diesem Fall sind viele der Antworten hier nicht falsch und enthalten gutes Know-how, aber sie verfehlen den Punkt der Frage. Es hilft nicht, dass Sie CK2 als Echtzeit-Strategiespiel bezeichnet haben, wenn es sich tatsächlich um ein großartiges Strategiespiel handelt . Das mag pingelig erscheinen, ist aber für die Probleme, mit denen Sie konfrontiert sind, sehr relevant.
Raphael Schmitz
1
Wenn Sie beispielsweise "Tausende von Zeichen" erwähnen, denken die Leute gleichzeitig an Tausende von 3D-Modellen oder Sprites auf dem Bildschirm - also in Unity an Tausende von GameObjects. In CK2 war die maximale Anzahl von Charakteren, die ich gleichzeitig sah, als ich auf meinen Platz schaute und dort 10-15 Leute sah (ich spielte allerdings nicht sehr weit). Genauso gut ist eine Armee mit 3000 Soldaten nur eine GameObject, die die Nummer "3000" anzeigt.
Raphael Schmitz
1
@ R.Schmitz Ja, ich hätte diesen Teil klarstellen sollen, dass jedem Charakter kein Spielobjekt zugeordnet ist. Wann immer nötig, wie den Charakter von einem Punkt zum anderen zu bewegen. Es wird eine separate Entität erstellt, die alle Informationen dieses Zeichens mit Ai-Logik enthält.
Paul p

Antworten:

24

Es gibt drei Dinge, die Sie berücksichtigen sollten:

  1. Verursacht es tatsächlich ein Leistungsproblem? 1000er sind eigentlich nicht viele. Moderne Computer sind furchtbar schnell und können mit vielen Dingen umgehen. Überwachen Sie, wie viel Zeit die Zeichenverarbeitung in Anspruch nimmt, und prüfen Sie, ob sie tatsächlich ein Problem verursacht, bevor Sie sich zu viele Sorgen machen.

  2. Wiedergabetreue von derzeit minimal aktiven Zeichen. Ein häufiger Fehler von Anfänger-Spielprogrammierern ist die Besessenheit, Off-Screen-Charaktere genau wie On-Screen-Charaktere genau zu aktualisieren. Das ist ein Fehler, niemand kümmert sich darum. Stattdessen müssen Sie versuchen, den Eindruck zu erwecken, dass Off-Screen-Charaktere immer noch agieren. Indem Sie die Anzahl der Aktualisierungszeichen reduzieren, die außerhalb des Bildschirms empfangen werden, können Sie die Verarbeitungszeiten erheblich verkürzen.

  3. Betrachten Sie datenorientiertes Design. Anstatt 1000 Zeichenobjekte zu haben und für jedes dieselbe Funktion aufzurufen, sollten Sie ein Array der Daten für die 1000 Zeichen haben und eine Funktionsschleife über die 1000 Zeichen haben, die jeweils nacheinander aktualisiert werden. Diese Art der Optimierung kann die Leistung erheblich verbessern.

Jack Aidley
quelle
3
Entität / Komponente / System funktioniert hierfür gut. Erstellen Sie jedes "System" für das, was Sie benötigen, lassen Sie es die Tausenden oder Zehntausenden von Zeichen (deren Komponenten) behalten und geben Sie dem System die "Zeichen-ID". Auf diese Weise können Sie die verschiedenen Datenmodelle getrennt und kleiner halten und tote Zeichen von Systemen entfernen, die sie nicht benötigen. (Sie können ein System auch vollständig entladen, wenn Sie es gerade nicht verwenden.)
Der Kommissar
1
Indem Sie die Anzahl der Aktualisierungszeichen reduzieren, die außerhalb des Bildschirms empfangen werden, können Sie die Verarbeitungszeiten erheblich verlängern. Meinst du nicht Abnahme?
Tejas Kale
1
@ TejasKale: Ja, korrigiert.
Jack Aidley
2
Tausend Charaktere sind nicht viel, aber wenn jeder von ihnen ständig prüft, ob er jeden der anderen kastrieren kann , hat dies einen großen Einfluss auf die Gesamtleistung ...
neugieriger Mann
1
Es ist immer am besten, dies tatsächlich zu überprüfen, aber es ist im Allgemeinen eine sichere Annahme, dass die Römer sich gegenseitig kastrieren wollen;)
odddannii
11

In dieser Situation würde ich die Verwendung von Komposition vorschlagen :

Das Prinzip, dass Klassen durch ihre Zusammensetzung ein polymorphes Verhalten und eine Wiederverwendung von Code erreichen sollten (indem Instanzen anderer Klassen enthalten werden, die die gewünschte Funktionalität implementieren)


In diesem Fall klingt es so, als wäre Ihre CharacterKlasse gottähnlich geworden und enthält alle Details darüber, wie ein Charakter in allen Phasen seines Lebenszyklus funktioniert .

Sie stellen beispielsweise fest, dass die toten Zeichen weiterhin benötigt werden - wie sie in den Stammbäumen verwendet werden. Es ist jedoch unwahrscheinlich, dass alle Informationen und Funktionen Ihrer lebenden Charaktere noch benötigt werden, um sie in einem Stammbaum anzuzeigen. Sie benötigen beispielsweise einfach Namen, Geburtsdatum und ein Porträtsymbol.


Die Lösung besteht darin, die einzelnen Teile von Ihnen Characterin Unterklassen aufzuteilen , deren CharacterInstanz der Eigentümer besitzt. Zum Beispiel:

  • CharacterInfo kann eine einfache Datenstruktur mit dem Namen, dem Geburtsdatum, dem Todesdatum und der Fraktion sein,

  • Equipmentkann alle Gegenstände haben, die dein Charakter hat, oder deren aktuelles Vermögen. Es kann auch die Logik haben, die diese in Funktionen verwaltet.

  • CharacterAIoder CharacterControllerkann alle Informationen enthalten, die über das aktuelle Ziel des Charakters, seine Nutzenfunktionen usw. benötigt werden. Und es kann auch die tatsächliche Aktualisierungslogik enthalten, die die Entscheidungsfindung / Interaktion zwischen seinen einzelnen Teilen koordiniert.

Sobald Sie den Charakter aufgeteilt haben, müssen Sie kein Alive / Dead-Flag mehr in der Update-Schleife aktivieren.

Stattdessen würden Sie einfach ein machen , AliveCharacterObjectdass die hat CharacterController, CharacterEquipmentund CharacterInfoSkripte angebracht. Um den Charakter zu "töten", entfernen Sie einfach die Teile, die nicht mehr relevant sind (wie die CharacterController) - es wird jetzt weder Speicher noch Verarbeitungszeit verschwendet.

Beachten Sie, dass dies CharacterInfowahrscheinlich die einzigen Daten sind, die tatsächlich für den Stammbaum benötigt werden. Indem Sie Ihre Klassen in kleinere Funktionen zerlegen, können Sie dieses kleine Datenobjekt nach dem Tod einfacher behalten, ohne den gesamten KI-gesteuerten Charakter behalten zu müssen.


Es ist erwähnenswert, dass dieses Paradigma das ist, für das Unity entwickelt wurde - und deshalb werden Dinge mit vielen separaten Skripten behandelt. Das Erstellen großer Gottobjekte ist selten der beste Weg, um Ihre Daten in Unity zu verarbeiten.

Bilkokuya
quelle
8

Wenn Sie eine große Datenmenge verarbeiten müssen und nicht jeder Datenpunkt durch ein tatsächliches Spielobjekt dargestellt wird, ist es normalerweise keine schlechte Idee, auf Unity-spezifische Klassen zu verzichten und einfach mit alten C # -Objekten zu arbeiten. Auf diese Weise minimieren Sie den Overhead. Sie scheinen hier also auf dem richtigen Weg zu sein.

Das Speichern aller lebenden oder toten Zeichen in einer Liste ( oder einem Array ) kann nützlich sein, da der Index in dieser Liste als kanonische Zeichen-ID dienen kann. Der Zugriff auf eine Listenposition über den Index ist sehr schnell. Es kann jedoch nützlich sein, eine separate Liste der IDs aller lebenden Zeichen zu führen, da Sie diese wahrscheinlich weitaus häufiger wiederholen müssen als die toten Zeichen.

Wenn Ihre Implementierung Ihrer Spielmechanik Fortschritte macht, möchten Sie möglicherweise auch untersuchen, welche anderen Arten von Suchvorgängen Sie am häufigsten durchführen. Wie "alle lebenden Charaktere an einem bestimmten Ort" oder "alle lebenden oder toten Vorfahren eines bestimmten Charakters". Es kann vorteilhaft sein, weitere sekundäre Datenstrukturen zu erstellen, die für diese Art von Abfragen optimiert sind. Denken Sie daran, dass jeder von ihnen auf dem neuesten Stand gehalten werden muss. Dies erfordert zusätzliche Programmierung und führt zu zusätzlichen Fehlern. Tun Sie dies also nur, wenn Sie eine bemerkenswerte Leistungssteigerung erwarten.

CKII " beschneidet " Zeichen aus seiner Datenbank, wenn es sie für unwichtig hält, um Ressourcen zu sparen. Wenn Ihr Stapel toter Charaktere in einem lang laufenden Spiel zu viele Ressourcen verbraucht, möchten Sie möglicherweise etwas Ähnliches tun (ich möchte dies nicht als "Garbage Collection" bezeichnen. Vielleicht als "respektvoller Inkremator"?).

Wenn Sie tatsächlich ein Spielobjekt für jeden Charakter im Spiel haben, kann das neue Unity ECS- und Jobs-System für Sie hilfreich sein. Es ist für den performanten Umgang mit einer Vielzahl sehr ähnlicher Spielobjekte optimiert. Aber es zwingt Ihre Softwarearchitektur in einige sehr starre Muster.

Übrigens, ich mag CKII sehr und die Art und Weise, wie es eine Welt mit Tausenden von einzigartigen AI-gesteuerten Charakteren simuliert. Ich freue mich darauf, Ihre Sicht auf das Genre zu spielen.

Philipp
quelle
Hallo, danke für die Antwort. Alle Berechnungen werden von einem einzigen GameObject Manager durchgeführt. Ich weise Spielobjekte nur dann einzelnen Akteuren zu, wenn dies erforderlich ist (z. B. wenn gezeigt wird, dass sich die Armee des Charakters von einer Position zur anderen bewegt).
Paul p
1
Like "all living characters in a specific location" or "all living or dead ancestors of a specific character". It might be beneficial to create some more secondary data-structures optimized for these kinds of queries.Aus meiner Erfahrung mit CK2-Modding kommt dies dem Umgang von CK2 mit den Daten sehr nahe. CK2 scheint Indizes zu verwenden, die im Wesentlichen grundlegende Datenbankindizes sind, wodurch es schneller wird, Zeichen für eine bestimmte Situation zu finden. Anstatt eine Liste mit Zeichen zu haben, scheint es eine interne Datenbank mit Zeichen zu geben, die alle Nachteile und Vorteile mit sich bringt.
Morfildur
1

Sie müssen nicht Tausende von Charakteren simulieren / aktualisieren, wenn sich nur wenige in der Nähe des Players befinden. Sie müssen nur aktualisieren, was der Spieler zum aktuellen Zeitpunkt tatsächlich sehen kann. Daher sollten Charaktere, die weiter vom Spieler entfernt sind, gesperrt werden, bis der Spieler näher an ihnen ist.

Wenn dies nicht funktioniert, weil Ihre Spielmechanik entfernte Charaktere benötigt, um den Zeitablauf anzuzeigen, können Sie sie in einem "großen" Update aktualisieren, wenn der Spieler näher kommt. Wenn Ihre Spielmechanik erfordert, dass jeder Charakter tatsächlich auf Ereignisse im Spiel reagiert, unabhängig davon, wo sich der Charakter in Bezug auf den Spieler oder das Ereignis befindet, kann dies dazu beitragen, die Häufigkeit zu verringern, mit der sich Charaktere weiter vom Spieler entfernt befinden aktualisiert (dh sie werden immer noch synchron mit dem Rest des Spiels aktualisiert, aber nicht so oft, so dass es eine leichte Verzögerung gibt, bevor entfernte Charaktere auf ein Ereignis reagieren, aber es ist unwahrscheinlich, dass dies ein Problem verursacht oder sogar vom Spieler bemerkt wird ). Alternativ können Sie einen hybriden Ansatz verwenden.

Micheal Johnson
quelle
Es ist ein RTS. Wir sollten davon ausgehen, dass zu einem bestimmten Zeitpunkt tatsächlich eine beträchtliche Anzahl von Einheiten auf dem Bildschirm angezeigt wird.
Tom
In einem RTS muss die Welt weitergehen, während der Spieler nicht hinschaut. Ein großes Update würde genauso lange dauern, aber beim Bewegen der Kamera in einem großen Ausbruch sein.
PStag
1

Klärung der Frage

Ich habe ein einfaches RTS-Spiel gemacht, das Hunderte von Charakteren wie Crusader Kings 2 in einer Einheit enthält.

In dieser Antwort gehe ich davon aus, dass das ganze Spiel wie CK2 sein soll, anstatt nur den Teil, in dem es darum geht, viele Charaktere zu haben. Alles, was Sie in CK2 auf dem Bildschirm sehen, ist einfach zu erledigen und gefährdet weder Ihre Leistung noch ist die Implementierung in Unity kompliziert. Die Daten dahinter werden dort komplex.

CharacterKlassen ohne Funktionalität

Also habe ich eine C # -Klasse namens "Character" erstellt, die alle Daten enthält.

Gut, denn ein Charakter in Ihrem Spiel besteht nur aus Daten. Was Sie auf dem Bildschirm sehen, ist nur eine Darstellung dieser Daten. Diese CharacterKlassen sind das Herzstück des Spiels und laufen als solche Gefahr, " Gottobjekte " zu werden. Daher würde ich extreme Maßnahmen dagegen empfehlen: Entfernen Sie alle Funktionen aus diesen Klassen. Eine Methode GetFullName(), die den Vor- und Nachnamen kombiniert, OK, aber keinen Code, der tatsächlich "etwas tut". Fügen Sie diesen Code in dedizierte Klassen ein, die eine Aktion ausführen. Beispiel: Eine Klasse Birthermit einer Methode Character CreateCharacter(Character father, Character mother)wird viel sauberer als diese Funktionalität in der CharacterKlasse.

Speichern Sie keine Daten im Code

Zum Speichern wäre es am einfachsten, skriptfähige Objekte zu verwenden

Nein. Speichern Sie sie im JSON-Format mit JsonUtility von Unity. Bei diesen CharacterKlassen ohne Funktionalität sollte dies trivial sein. Dies funktioniert sowohl für die Ersteinrichtung des Spiels als auch für die Speicherung in Savegames. Es ist jedoch immer noch langweilig, deshalb habe ich nur die einfachste Option in Ihrer Situation angegeben. Sie können auch XML oder YAML oder ein beliebiges Format verwenden, sofern es noch von Menschen gelesen werden kann, wenn es in einer Textdatei gespeichert ist. CK2 macht das Gleiche, eigentlich machen es die meisten Spiele. Es ist auch ein ausgezeichnetes Setup, um es Leuten zu ermöglichen, Ihr Spiel zu modifizieren, aber das ist ein Gedanke für viel später.

Denken Sie abstrakt

Ich habe eine einfache Überprüfung hinzugefügt, um sicherzustellen, dass das Zeichen während der Verarbeitung [...] "lebendig" ist, aber ich kann "Zeichen" nicht entfernen, wenn er tot ist, da ich seine Informationen beim Erstellen des Stammbaums benötige.

Dieser ist leichter gesagt als getan, weil er oft mit der natürlichen Denkweise kollidiert. Sie denken auf "natürliche" Weise an einen "Charakter". In Bezug auf Ihr Spiel scheint es jedoch mindestens zwei verschiedene Arten von Daten zu geben, die "ein Charakter" sind: Ich werde es ActingCharacterund nennen FamilyTreeEntry. Ein toter Charakter FamilyTreeEntrymuss nicht aktualisiert werden und benötigt wahrscheinlich viel weniger Daten als ein aktiver ActingCharacter.

Raphael Schmitz
quelle
0

Ich werde aus ein wenig Erfahrung sprechen, von einem starren OO-Design zu einem Entity-Component-System (ECS) -Design.

Vor einiger Zeit war ich genau wie Sie , ich hatte eine Reihe verschiedener Arten von Dingen, die ähnliche Eigenschaften hatten, und ich baute verschiedene Objekte aus und versuchte, sie mithilfe der Vererbung zu lösen. Eine sehr kluge Person sagte mir , dass ich das nicht tun und stattdessen Entity-Component-System verwenden soll.

Jetzt ist ECS ein großes Konzept, und es ist schwierig, es richtig zu machen. Es steckt viel Arbeit dahinter, Entitäten, Komponenten und Systeme richtig aufzubauen. Bevor wir dies jedoch tun können, müssen wir die Begriffe definieren.

  1. Entität : Dies ist das Ding , der Spieler, das Tier, der NPC, was auch immer . Es ist eine Sache, an die Komponenten angeschlossen werden müssen.
  2. Komponente : Dies ist das Attribut oder die Eigenschaft , z. B. "Name" oder "Alter" oder "Eltern" in Ihrem Fall.
  3. System : Dies ist die Logik hinter einer Komponente oder einem Verhalten . Normalerweise erstellen Sie ein System pro Komponente, dies ist jedoch nicht immer möglich. Außerdem müssen Systeme manchmal andere Systeme beeinflussen.

Also, hier ist, wohin ich damit gehen würde:

Erstellen IDSie in erster Linie eine für Ihre Charaktere. Ein int, Guid, was Sie wollen. Dies ist die "Entität".

Zweitens sollten Sie über die verschiedenen Verhaltensweisen nachdenken, die Sie haben. Dinge wie der "Stammbaum" - das ist ein Verhalten. Erstellen Sie ein System, das alle diese Informationen enthält, anstatt dies als Attribute für die Entität zu modellieren . Das System kann dann entscheiden, was damit zu tun ist.

Ebenso wollen wir ein System für "Ist der Charakter lebendig oder tot?" Dies ist eines der wichtigsten Systeme in Ihrem Design, da es alle anderen beeinflusst. Einige Systeme können die "toten" Zeichen löschen (z. B. das "Sprite" -System), andere Systeme können die Dinge intern neu anordnen, um den neuen Status besser zu unterstützen.

Sie bauen beispielsweise ein "Sprite" - oder "Drawing" - oder "Rendering" -System auf. Dieses System hat die Verantwortung zu bestimmen, mit welchem ​​Sprite der Charakter angezeigt werden soll und wie er angezeigt werden soll. Wenn ein Charakter stirbt, entferne ihn.

Zusätzlich ein "KI" -System, das einem Charakter sagen kann, was zu tun ist, wohin er gehen soll usw. Dies sollte mit vielen anderen Systemen interagieren und basierend auf diesen Entscheidungen treffen. Auch hier können tote Charaktere wahrscheinlich aus diesem System entfernt werden, da sie eigentlich nichts mehr tun.

Ihr "Name" -System und Ihr "Family Tree" -System sollten den Charakter (lebendig oder tot) wahrscheinlich im Speicher behalten. Dieses System muss diese Informationen abrufen, unabhängig vom Status des Charakters. (Jim ist immer noch Jim, auch nachdem wir ihn begraben haben.)

Dies bietet Ihnen auch den Vorteil einer Änderung, wenn ein System effizienter reagiert : Das System verfügt über einen eigenen Timer. Einige Systeme müssen schnell ausgelöst werden, andere nicht. Hier beginnen wir mit dem, was ein Spiel effizient laufen lässt. Wir müssen das Wetter nicht jede Millisekunde neu berechnen, wir können das wahrscheinlich alle 5 oder so tun.

Es gibt Ihnen auch mehr kreative Hebelwirkung: Sie können ein "Pathfinder" -System erstellen, das die Berechnung eines Pfades von A nach B übernimmt und bei Bedarf aktualisiert werden kann, sodass das Bewegungssystem sagen kann, "wo muss ich hin" als nächstes gehen? " Wir können diese Bedenken jetzt vollständig trennen und effektiver darüber nachdenken. Bewegung muss nicht den Weg finden, sondern nur dorthin gelangen.

Sie sollten einige Teile eines Systems nach außen aussetzen. In Ihrem PathfinderSystem möchten Sie wahrscheinlich eine Vector2 NextPosition(int entity). Auf diese Weise können Sie diese Elemente in streng kontrollierten Arrays oder Listen aufbewahren. Sie können kleinere structTypen verwenden, mit denen Sie Komponenten in kleineren, zusammenhängenden Speicherblöcken aufbewahren können, wodurch Systemaktualisierungen viel schneller durchgeführt werden können. (Insbesondere wenn die externen Einflüsse auf ein System minimal sind, muss es sich nur noch um seinen internen Zustand kümmern, wie z Name.

Aber, und ich kann das nicht genug betonen, jetzt Entityist es nur ein ID, einschließlich Kacheln, Objekte usw. Wenn eine Entität nicht zu einem System gehört, wird das System sie nicht verfolgen. Dies bedeutet, dass wir unsere "Baum" -Objekte erstellen, sie in den Systemen Spriteund speichern können Movement(die Bäume bewegen sich nicht, aber sie haben eine "Position" -Komponente) und sie von den anderen Systemen fernhalten können. Wir brauchen keine spezielle Liste mehr für Bäume, da das Rendern eines Baumes abgesehen von Paperdolling nicht anders ist als ein Charakter. (Was das SpriteSystem steuern kann oder was das System steuern Paperdollkann.) Jetzt NextPositionkann unser leicht umgeschrieben werden: Vector2? NextPosition(int entity)und es kann eine nullPosition für Entitäten zurückgeben, die es nicht interessiert. Wir wenden dies auch auf unsere an NameSystem.GetName(int entity), es kehrt nullfür Bäume und Felsen zurück.


Ich werde dies zu Ende bringen, aber die Idee hier ist, Ihnen einige Hintergrundinformationen zu ECS zu geben und wie Sie es wirklich nutzen können, um Ihnen ein besseres Design für Ihr Spiel zu geben. Sie können die Leistung steigern, nicht verwandte Elemente entkoppeln und die Dinge besser organisieren. (Dies passt auch gut zu funktionalen Sprachen / Setups wie F # und LINQ. Ich empfehle dringend, F # zu überprüfen, wenn Sie dies noch nicht getan haben. Es passt sehr gut zu C #, wenn Sie sie zusammen verwenden.)

Der Kommissar
quelle
Hallo, danke für eine so detaillierte Antwort. Ich verwende nur einen GameObject Manager, der den Verweis auf alle anderen In-Game-Charaktere enthält.
Paul p
Die Entwicklung in Unity dreht sich um Entitäten GameObject, die nicht viel bewirken, aber eine Liste von ComponentKlassen haben, die die eigentliche Arbeit erledigen. Vor einem Jahrzehnt gab es einen Paradigmenwechsel in Bezug auf den ECS-Kreisverkehr , da es sauberer ist, den handelnden Code in separate Systemklassen einzuteilen. Unity hat kürzlich auch ein solches System implementiert, aber ihr GameObjectSystem ist und war immer ein ECS. OP verwendet bereits ein ECS.
Raphael Schmitz
-1

Wenn Sie dies in Unity tun, ist der einfachste Ansatz folgender:

  • Erstelle ein Spielobjekt pro Charakter oder Einheitentyp
  • Speichern Sie diese als Fertighäuser
  • Sie können dann bei Bedarf ein Fertighaus instanziieren
  • Wenn ein Charakter getötet wird, zerstöre das Spielobjekt und es nimmt keine CPU oder keinen Speicher mehr ein

In Ihrem Code können Sie Verweise auf die Objekte in einer Liste aufbewahren, um zu verhindern, dass Sie Find () und seine Variationen ständig verwenden. Sie tauschen CPU-Zyklen gegen Speicher, aber eine Liste von Zeigern ist ziemlich klein, sodass selbst mit ein paar tausend Objekten kein großes Problem auftreten sollte.

Während Sie Ihr Spiel durcharbeiten, werden Sie feststellen, dass einzelne Spielobjekte Ihnen unzählige Vorteile bieten, einschließlich Navigation und KI.

Tom
quelle