Jump to content
Unity Insider Forum

GameObject durch Position finden


Prayer90

Recommended Posts

Hallo zusammen,

Ich möchte von einem Gameobjekt auf ein anderes zugreifen. Das GameObjekt kann häufiger in der Szene vorhanden sein und muss sich bei der Suche selbst ausschließen.

Ich kenne von dem anderen Objekt die genaue transform.position.

Kann man damit irgendwie eine ich nenne es mal "GameObjekt = FindFromPosition(x, y);" Funktion basteln?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moin @Prayer90

Dafür müsstest du dir ne eigene funktion schreiben und dann zum Beispiel über alle GameObjects gehen und die position vergleichen. Das ist ZIEMLICH ineffizient und ich würde dir je nach menge der GameObjects die du hast und nach häufigkeit des funktionsaufrufs stark davon abraten.

Ich würde dir empfehlen eine andere möglichkeit einzubauen .. zum beispiel eine eigene Komponente (Monobehaviour) auf dem gameObject das sich dann z.B. Bei einer anderen Klasse (z.B. einem LocationService oder so) registriert .. wenn du dann ein GO an einer position haben willst musst du nur alle registrierten GOs (mit dieser komponente) durchsuchen und nicht alle GOs im spiel

Link zu diesem Kommentar
Auf anderen Seiten teilen

Bevor du dir da was zusammenschraubst, denke ich, dass du noch ein paar Schritte zurück gehen solltest. Du kennst die genaue Position des Objekts, wie kommt das? Kannst du an der Stelle, wo die Position übermittelt wird, nicht vielleicht auch einfach direkt eine Referenz auf das Objekt übermitteln? Ich gehe stark davon aus, dass du eine bessere Lösung bauen kannst, als die Position zu benutzen. Wie sieht den dein Kontext aus; um was für Objekte handelt es sich, und wie findet die "Begegnung" statt?

Davon abgesehen gibt es das Konzept der "Beschleuningsstrukturen", in diesem Fall z.B. "Spatial Hashmaps". Das ist eine Datenstruktur (wie z.B. eine Liste), wo man Dinge einfügen und rausnehmen kann, und diese Dinge werden Sektoren zugeordnet, in dem sie sind. Mit einer solchen Spatial Hashmap kannst du dann alle Objekte abfragen, die in einem Sektor sind - und in welchem Sektor dein Objekt ist, weißt du ja aufgrund der Position, die bekannt ist. Dann brauchst du die ganzen Objekte in allen anderen Sektoren gar nicht erst betrachten. Damit löst man das Problem, das @Cxyda83 angesprochen hat, während ich noch am Schreiben war :)

Das ist nicht superschwer zu implemtieren, aber Anfängerkram ist's auch nicht gerade. Du hast allerdings auch Beschleunigungsstrukturen direkt in Unity eingebaut, und zwar in der Physikengine. Mit so Sachen wie Physics.OverlapSphere kannst du Dinge in Arealen finden, solange sie Collider haben.

Aber da ich recht sicher bin, dass der Weg über die Position des Objekts in deinem Fall ein unnötiger Umweg ist, erzähle lieber erstmal, was du da so baust :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Schade, hätten nicht erwartet, dass das so kompliziert zu lösen ist.
Aber vermutlich ist mein Ansatz an dieser Stelle auch einfach nicht der Richtige.

Es ist etwas schwer zu erklären, aber im Prinzip geht es um Folgendes:

  • Ich habe ein gridbasiertes Spielfeld.
  • Der Spieler hat die Möglichkeit auf diesem Grid Mauern zu platzieren, die sich automatisch zueinander ausrichten sollen. (Schritt 1) Bezogen auf das Grid haben alle Mauern eine Grundfläche von 2x2 Feldern.
  • Beim Platzieren eines neuen Mauersegments, sollen bereits bestehende, direkt angrenzende Mauern einen Impuls bekommen, das nebenan etwas Neues angrenzt.
  • Der Impuls beinhaltet: "hey... Da grenzt was an" und "hey... die Nachbarmauer befindet sich an folgender Position um mich herum". (Schritt 2)

Am Ende soll eine durchgehende Mauer entstehen die sich Gridsegment für Gridsegment in ihrer Richtung anpasst. (Schritt 3)

 

Meine Idee zur Umsetzung:

  1. war es ein Prefab zu bauen (s.Anhang), das aus einem leeren Gameobjekt (mein Elternobjekt) besteht, was die eigentliche Position im Grid abfragt und ein Zeichen gibt, kann ich an der gewünschten Position bauen oder nicht (bis hier hin funktioniert das Ganze schon).
  2. Zusätzlich enthält das Elternobjekt 8 Childobjekte an den Ecken jeder GridZelle (Anhang rot). Jedes besitzt eine eigene ID. Anhand dieser ID, soll die Information der Position, direkt angrenzender Mauersegmente geliefert werden.
    Beim Platzieren eines neuen Mauersegments liegen diese Childobjekte (pink) dann genau übereinander. An dieser Stelle dachte ich, ich kann eine Suche mithilfe der Position des Objektes starten. Aber scheinbar muss ich dieses via Collider realisieren. 

    Für das, was ich vorhabe, brauche ich die Information der ID aller kollidierenden Childobjekte (pink).
     
  3. Somit könnte ich anschließend den Aufbau der Mauersegmente bestimmen.

 

Mit Physics.OverlapSphere habe ich gestern schon ein wenig probiert, bin aber noch zu keinem brauchbaren Ergebnis gekommen. Ich habe immer nur das Elternobjekt des Prefab gefunden. Leider nicht die gewünschte Information der Childobjekte.

 

 

Schritt1.png

Schritt2.png

Schritt3.png

Link zu diesem Kommentar
Auf anderen Seiten teilen

joar das ist das typische Problem das du hier wie ein Mensch denkst (in einem 3D raum). Das ist aber nicht der Weg wie computer so etwas lösen. Im speicher liegt im prinzip alles kreuz und qure verteilt und wenn du so etwas wie ein grid haben willst ist das quasi nichts anderes als eine liste mit speicheradressen zu diesem objekt.

Ein GameObject hat viele eigenschaften wie z.B. die position. Kennst du die Referenz zu dem Objekt kannst du auch die Position abfragen. Das ist das was Sascha meinte.

Was du machen willst ist zum beispiel die IDs und die gameObjects in einem Dictionary ablegen

Dictionary<int, GameObject> gameObjectDictionary = new Dictionary<int, GameObject>();

  // dann kannst du beim erstellen alle GameObjects z.B. So adden
  gameObjectDictionary[ID] = myGameObject;
  
  // und wenn du dann dein GameObject wieder finden willst machst du
  
  GameObject myGameObject = gameObjectDictionary[ID];
  

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dankeschön:),

das Dictionary scheint für mich als Lösungsansatz wirklich zu funktionieren.

Als Key verwende ich nun einen String der eine Kombination aus der x-Koordinate einem Sonderzeichen und der Y-Koordinate besteht.

Über das Anpassen der Koordinaten kann ich so gezielt umliegende GameObjekte ansprechen. Bzw. überprüfen, ob diese überhaupt vorhanden sind.

Link zu diesem Kommentar
Auf anderen Seiten teilen

sehr schön.

Du speicherst dir die GOs doch sicherlich eh in einem Array bzw einem grid ab oder ? Dann kannst du ja auch das verwenden und dir mithilfe der x und y koordinate (wenn du die eh schon hast) das GO holen und einfach mit x: +-1 und y:+-1 alle nachbarn holen 🤔

aber ja mit dem Dictionary geht auch

Link zu diesem Kommentar
Auf anderen Seiten teilen

In dem Fall ist das eigentlich nicht mehr notwenig. 

Mein Grid besteht eigentlich nur aus int's die "vor Level beginn" mein Terrain abstecken.

Über zwei Schleifen werden alle Zellen ausgelesen und dementsprechend Objekte platziert.

Danach nutze ich es nur noch um "bebaubare" Bereiche festzulegen.

Die Überlegung das Ganze zu erweitern um direkt Objekte darin zu speichern ist allerdings eine Überlegung Wert. Daran habe ich ehrlich gesagt noch gar nicht gedacht😀

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hab mich nun doch dazu entschieden das Ganze etwas zu vereinfachen.

Es gibt nun keine halben Grid Felder mehr. Damit kann man nun nur noch direkt angrenzend an alle vier Seiten bauen. Vielen Dank für alle hilfreichen Tipps hier.

Dictionary in Kombination mit dem Vector2 als Key wurde erfolgreich umgesetzt:D. Ich wollte das Ergebnis nur gerne nochmal anhängen, da ich mich freue, dass es so schön funktioniert:)

Danke.png

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...