Wie erstelle ich ein ziehbares Objekt, das an Hindernissen im Weg einrastet?

8

Ich bringe noch eine weitere Frage zum Ziehen mit der Maus (ich verwende Unity mit C #), aber mit einem weniger verbreiteten Detail: dem Vorhandensein von Hindernissen in der Mitte des Weges, durch den das Ziehen erfolgt (3D-Raum, nicht 2D) .

Lassen Sie mich erklären. Angenommen, ich habe eine Ebene, über die ich einen Würfel namens "obj" ziehen möchte. Das ist einfach. Hier ist meine einfache Implementierung dafür:

void Update () {
  Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  RaycastHit hit;
  if(Physics.Raycast(ray, out hit, 1000000))
  obj.transform.position = new Vector3(hit.point.x,0.25F,hit.point.z);
}

Es klappt. Angenommen, ich habe noch ein paar andere Würfel über dem Flugzeug, die die Hindernisse darstellen. Wenn sich der Spieler "obj" über das Flugzeug bewegt, sollte diese Bewegung offensichtlich durch die Hindernisse blockiert werden. Und dann, während "obj" mit den Hindernissen kollidiert, sollte es sich nur an den Seiten dieses Hindernisses bewegen. Wenn die Maus bewegt wird und "obj" nicht mehr mit Hindernissen kollidiert, wird die Bewegung im freien Ziehstil wieder fortgesetzt.

Das Objekt wird auf ein Hindernis gezogen und an dessen Rand angehalten. Es wird dann fortgesetzt, wenn das Ziehen das Hindernis passiert

Um die Herausforderung zu erschweren, bemühe ich mich, dies ohne die Verwendung von RigidBody-Komponenten an den Hindernissen zu erreichen (das gezogene Objekt kann es haben). Irgendwelche Ideen, wie dies am effizientesten erreicht werden kann? Danke vielmals!

BEARBEITEN: Kommentatoren haben mich darauf aufmerksam gemacht, dass ich erwähnen sollte, dass sich Objekte beim Einrasten drehen dürfen.

EDIT 2: Angesichts der Schwierigkeit der ursprünglichen Formulierung habe ich die Frage geändert, die die Verwendung von Rigidbody-Komponenten an den gezogenen Objekten erlaubt. Die Lösung kann einfach keine Rigidbody-Komponenten an den Hindernissen verwenden.

MAnd
quelle
Bewegen Sie beliebige konvexe Formen - sind sie immer vierseitig? Sind sie immer 2D?
Steven
Darf ich wissen, warum Sie Rigidbodies nicht verwenden? Sie sind der einfachste Weg, um das zu tun, was Sie möchten, ohne den bereits in Unity verfügbaren Code neu implementieren zu müssen.
EvilTak
@EvilTak Ich lerne lieber, wie man mit der Geometrie umgeht, die mit der Aufgabe verbunden ist, und aus Leistungsgründen verwende ich Rigidbodies nicht gerne, es sei denn, dies ist wirklich wirklich unvermeidlich. In diesem speziellen Fall werde ich viele tausend Objekte haben, die sich als Hindernisse verhalten
6.
Übrigens, danke an @Anko (oder an denjenigen, der es getan hat), der dieses animierte Bild aufgenommen hat, um das Problem zu veranschaulichen! Ich dachte immer noch über den besten Weg nach.
6.
1
@Steven und EvilTak: Das Objekt darf sich drehen, die Hindernisse sollten sich nicht drehen. Übliche Methoden zur Erkennung von Kollisionen scheinen nicht ausreichend zu sein: Das Hauptobjekt gelangt immer wieder in die Objekte.
7.

Antworten:

2

Es ist schwierig, eine Kollision zu erkennen, ohne dass starre Körper beteiligt sind. Da Sie jedoch Würfel verwenden, können Sie möglicherweise Bounds.Intersects verwenden . Überprüfen Sie bei jeder Aktualisierung, ob sich die Grenzen des gezogenen Objekts mit den Grenzen von Hindernissen überschneiden. Wenn ja, können Sie Folgendes versuchen:

  1. Deaktivieren Sie den Mesh-Renderer für das gezogene Objekt, um es unsichtbar zu machen (aber ziehen Sie es weiter).
  2. Legen Sie ein sichtbares Platzhalterobjekt ab, das mit dem gezogenen Objekt an der letzten Position vor dem Grenzübergang identisch ist (jetzt sieht es so aus, als ob das Objekt gestoppt wurde, aber Sie ziehen das Original wirklich immer noch).
  3. Überprüfen Sie bei jeder Aktualisierung, ob sich die Grenzen des Objekts, das Sie noch ziehen, mit den Grenzen eines Hindernisses überschneiden.
  4. Wenn sich die Grenzen des gezogenen Objekts nicht mehr mit denen eines Hindernisses überschneiden, löschen / deaktivieren Sie das Platzhalterobjekt und aktivieren Sie den Mesh-Renderer erneut, damit das gezogene Objekt es wieder sichtbar macht.

Sie hören nie auf, den Block zu ziehen. Dem Benutzer wird lediglich angezeigt, dass der Block nicht mehr gezogen wird, während er sich mit einem Hindernis überschneidet.

Evan
quelle
Basierend auf früheren Kommentaren und Ihrer Antwort habe ich die Frage bearbeitet, um die Beantwortung zu vereinfachen: Nehmen wir nun an, Rigidbody könnte für das ziehbare Objekt oder seine Platzhalter verwendet werden. Rigidbody konnte einfach nicht für die Hindernisse verwendet werden.
MAnd
1

Ohne es selbst getan zu haben, würde ich Folgendes versuchen:

  1. Entscheiden Sie, wie hoch ein Hindernis in der Ebene sein muss, um Ihr gezogenes Objekt zu blockieren (wobei "hoch" bedeutet, dass es entlang der entsprechenden Achse entfernt wird - ich würde dasjenige annehmen, das zur Kamera zeigt).
  2. Speichern Sie bei jedem Update die Position Ihres Raycast-Treffers.
  3. Überprüfen Sie bei jeder Aktualisierung vor dem Speichern der Position des aktuellen Raycast-Treffers die Position des aktuellen Raycast-Treffers mit der Position des vorherigen Raycast-Treffers.
  4. Wenn der Unterschied> = Blockierhöhe ist, stoppen Sie Ihr sich bewegendes Objekt an der vorherigen Raycast-Trefferposition.

Es scheint mir, dass, wenn Sie möchten, dass Ihr Objekt entlang einer schrägen Ebene eines Hindernisses gezogen wird, die Transformation einfach weiterhin der Position des letzten Raycast-Treffers folgt.

Evan
quelle
Vielen Dank für Ihre Antwort, @Evan. Diese Lösung wäre jedoch nicht korrekt. Angenommen, der RayCast wird von der Mitte des Begrenzungsrahmens des ziehbaren Objekts abgefeuert. Was ist, wenn das Hindernis im Weg nur einen Teil des ziehbaren Objekts blockiert, der sich links oder rechts vom Strahlenwurf befindet? Selbst wenn wir die Anzahl der geworfenen Strahlen erhöhen (was exponentiell hoch werden kann, wenn das ziehbare Objekt in 360 ° -Richtungen in den X-, Z-Dimensionen gezogen werden kann), könnte es immer noch sein, je nachdem, wie klein das Hindernis im Verhältnis zum ziehbaren Objekt ist Zwischen den Strahlen geworfen werden - und daher nicht erkannt werden
am
Okay, ich glaube ich verstehe was du meinst.
Evan