STU Geschrieben 9. August 2020 Melden Share Geschrieben 9. August 2020 Hi, kann man bei einem Boxcollider2D die Seiten einzeln ansprechen? Ich würde gerne das so haben, wenn ich von oben drauf springe, dass etwas anderes passiert als wenn ich seitlich getroffen werden. Aktuell habe ich zwei collider einem in der Hauptfigur und einem in einem EmptyBody darunter. Das hat alles funktioniert bis ich einen ridigbody eingefügt habe. Jetzt gibt es probleme im EmptyBody er wird zwar noch erkannt aber das Skript in welchem ein Ereignis passieren soll, bei Kollision, funktioniert nicht mehr. Nehme ich den rigidbody wirder raus läuft alles wieder wie gehabt. Danke Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Thariel Geschrieben 9. August 2020 Melden Share Geschrieben 9. August 2020 Du hast bei der Kollision beide Objekte und kannst ganz einfach ermitteln, wo welches ist anhand von transform.position. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
STU Geschrieben 9. August 2020 Autor Melden Share Geschrieben 9. August 2020 Hi Thariel, dann muss ich haber vorher meine größe von dem Collider kennen, oder? Ich würde das skipt gerne für verschiedene gegner anwenden. Gibt es da eine möglichkeit? Wenn ich es ermittelt habe, dann mit if abfragen ob der eine höher ist als der andere? Danke Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 9. August 2020 Melden Share Geschrieben 9. August 2020 Gibt verschiedene Arten, das zu machen, aber eine Variante wäre natürlich, sich den Normalenvektor der Kollision anzuschauen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Thariel Geschrieben 9. August 2020 Melden Share Geschrieben 9. August 2020 Die grösse des BoxCillider2D kannst du natürlich schon ermitteln. Hier siehst du alles Relevante zum BoxCollider2D: https://docs.unity3d.com/ScriptReference/BoxCollider2D.html Interessant sind da sicher size und bounds. Wenn dein Charakter zum Beispiel auf ein Gegner springen soll, so wie in Mario, dann kannst du einfach das Zentrum der Gegner-BoxCollider nehmen und die Hälfte der Höhe der Box addieren. Das selbe machst du mit der Charakter Box, aber subtrahierst die Halbe Höhe. Wenn der Y Wert nun etwa gleich gross ist, ist der Charakter auf den Gegner gesprungen. Aber du kannst auch einfach mehrere BoxCollider nehmen. Das ist sicher am einfachsten. Du kannst auch nach der Kollision noch ein Linecast machen und dann hast du einen genauen HitPoint, aber die Seite musst du dann immer noch ermitteln. Es gibt da wirklich viele Möglichkeiten. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
STU Geschrieben 9. August 2020 Autor Melden Share Geschrieben 9. August 2020 Das klingt interessant und ich werde es morgen auf jeden Fall mal ausprobieren. Noch eine Anfängerfrage 😄 Wenn ich zwei collider habe und die mit Tigger anspreche kann ich ja z.b mit OnTiggerEnter2D (Boxcollider2D) oder eben Circlecollider machen. Wie macht man das mit oncollisionenter2d das man einen ganz bestimmten collider anspricht? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 9. August 2020 Melden Share Geschrieben 9. August 2020 Wenn du die Kontaktpunkte und die Normalen-Vektoren bei einer Kollision ausliest, dann sieht das in etwa so aus. An der Richtung der (beiden) Normalenvektoren kannst du also erkennen, auf welcher Seite des Box-Colliders die Kollision stattgefunden hat (wie Sascha schon geschrieben hatte). (rot = Normalenvektoren / blau = Kollisionspunkte / grün Boxcollider) Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
STU Geschrieben 10. August 2020 Autor Melden Share Geschrieben 10. August 2020 Das Thema ist für mich wirklich interessant. Das wird man aber nicht so einfach erklären können. Kennt ihr vielleicht ein gutes Video oder eine Internetseite wo das genauer erklärt wird? Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
STU Geschrieben 10. August 2020 Autor Melden Share Geschrieben 10. August 2020 Hi, ich habe mal so angefangen. Das habe ich uf der Seite von Unity gefunden. In der Console wird das auch angezeigt. In der erklärung steht, dass der Vektor auch in der SceneView sichtbar ist. Denke mal so wie oben in dem Bild. Ich sehe die Linien aber nicht. Was muss ich einstellen das ich diese auch sehe? void OnCollisionEnter(Collision other) { print("Points colliding: " + other.contacts.Length); print("First normal of the point that collide: " + other.contacts[0].normal); } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 10. August 2020 Melden Share Geschrieben 10. August 2020 vor 15 Minuten schrieb STU: Das habe ich uf der Seite von Unity gefunden. In der Console wird das auch angezeigt. In der erklärung steht Wär halt irgendwo sinnvoll, wenn du mal verlinkst, was du da gefunden hast. Auf allen Seiten, die ich jetzt extra rausgesucht habe; von denen ich angenommen habe, du könntest sie meinen, steht das im Beispielcode, wie man das macht. https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnCollisionEnter.html https://docs.unity3d.com/ScriptReference/Collision-contacts.html Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
STU Geschrieben 10. August 2020 Autor Melden Share Geschrieben 10. August 2020 Hi, ich habe zwar noch nicht die Linien sichtbar bekommen, dafür klappt es jetzt mit dem collider. Wenn ich oben drauf springe verschieben sie und wenn ich sie seitlich berühre, verliere ich Leben 😄 also schon mal vielen Dank für die Tipps. Auf die gleiche weiße habe ich es so programmiert, wenn ein Gegner seitlich einen collider trifft, dass er umdreht. Dabei ist mir aufgefallen, dass dies bei boxcollider funktioniert, aber nicht bei edgecollider. Was ist der Unterschied? Ich verwende obcollisionEnter2D. Ich kann morgen auch das Skript hochladen wenn das hilft. zu den Linien hatte ich hier nachgeschaut. https://docs.unity3d.com/ScriptReference/ContactPoint-normal.html Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Thariel Geschrieben 10. August 2020 Melden Share Geschrieben 10. August 2020 vor 58 Minuten schrieb STU: ich habe zwar noch nicht die Linien sichtbar bekommen Die grünen Linien der BoxCollider siehst du ja und die anderen wurden gezeichnet. Du kannst mit der Gizmos Klasse selber Linien und vieles mehr zeichnen: https://docs.unity3d.com/ScriptReference/Gizmos.html Zum Beispiel kannst du genau diese Funktion in dein Script kopieren und es wird eine gelbe Kugel im Editor Window gezeichnet. Du kannst deine eigene Funktion schreiben um Dinge zu visualisieren und so verstehen, ob dein Script richtig arbeitet. void OnDrawGizmos() { // Draw a yellow sphere at the transform's position Gizmos.color = Color.yellow; Gizmos.DrawSphere(transform.position, 1); } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Zer0Cool Geschrieben 11. August 2020 Melden Share Geschrieben 11. August 2020 Ich hatte die Punkte und Linien so "gemalt" und den Quellcode unterschlagen, da es quick und dirty war, aber wenn es dir hilft. Diese Klasse an den 2D-Collider hängen der die Collision bekommt (die Gizmos siehst du nur im Sceneview). Wenn gerade keine Collision stattfindet zeichnet er trotzdem die letzte Collision. using System.Collections; using System.Collections.Generic; using UnityEngine; public class DrawCollider2D : MonoBehaviour { private List<Vector3> contactPoints; private List<Vector3> normalPoints; void OnCollisionEnter2D(Collision2D collision) { contactPoints = new List<Vector3>(); normalPoints = new List<Vector3>(); ContactPoint2D[] contactPoint2d = collision.contacts; foreach (ContactPoint2D cPoint in contactPoint2d) { contactPoints.Add(cPoint.point); normalPoints.Add(cPoint.normal); } } void OnDrawGizmosSelected() { if (contactPoints != null) { Gizmos.color = Color.blue; foreach (Vector3 cPoint in contactPoints) { Gizmos.DrawWireSphere(cPoint, 0.02f); } } if (normalPoints != null) { Gizmos.color = Color.red; int i = 0; foreach (Vector3 nPoint in normalPoints) { Gizmos.DrawLine(contactPoints[i], contactPoints[i] + nPoint); i++; } } } } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
STU Geschrieben 12. August 2020 Autor Melden Share Geschrieben 12. August 2020 Hi Zer0Cool, vielen vielen Dank für deine Mühe, funktioniert super Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
MaZy Geschrieben 12. August 2020 Melden Share Geschrieben 12. August 2020 Also die Regeln lauten bei zwei GameObjects mit Collidern muss einer davon Rigidbody haben, damit sie mit einander kollidieren können und da wird auch OnCollision usw. gecallt. Daher komisch, dass es bei dir nicht mehr geht, wenn man Rigidbody hinzufügt. vor 18 Stunden schrieb Zer0Cool: Ich hatte die Punkte und Linien so "gemalt" und den Quellcode unterschlagen, da es quick und dirty war, aber wenn es dir hilft. Diese Klasse an den 2D-Collider hängen der die Collision bekommt (die Gizmos siehst du nur im Sceneview). Wenn gerade keine Collision stattfindet zeichnet er trotzdem die letzte Collision. using System.Collections; using System.Collections.Generic; using UnityEngine; public class DrawCollider2D : MonoBehaviour { private List<Vector3> contactPoints; private List<Vector3> normalPoints; void OnCollisionEnter2D(Collision2D collision) { contactPoints = new List<Vector3>(); normalPoints = new List<Vector3>(); ContactPoint2D[] contactPoint2d = collision.contacts; foreach (ContactPoint2D cPoint in contactPoint2d) { contactPoints.Add(cPoint.point); normalPoints.Add(cPoint.normal); } } void OnDrawGizmosSelected() { if (contactPoints != null) { Gizmos.color = Color.blue; foreach (Vector3 cPoint in contactPoints) { Gizmos.DrawWireSphere(cPoint, 0.02f); } } if (normalPoints != null) { Gizmos.color = Color.red; int i = 0; foreach (Vector3 nPoint in normalPoints) { Gizmos.DrawLine(contactPoints[i], contactPoints[i] + nPoint); i++; } } } } Muss dein Code kritisieren . Jedes mal contactPoints = new List<Vector3>(); zu machen finde ich nicht gut, aber ist in dem Beispiel ist es nicht so schlimm. Man kann dennoch da contactPoints.Clear() benutzen. New Object lässt den GarbageCollector arbeiten. Wie gesagt: In dem Beispiel ist das jetzt nicht schlimm, aber hätten wir 500 Objekte, die mit einander Kollidieren dann vllt schon. Warum ich generell das nicht machen würde ist, wenn man Logger.contactPoints = contactPoints hat und man nun contactPoints = new macht.. dann ist Logger.contactPoints nicht null, sondern hat noch den Reference zu alten Speicher von contactPoints. Das heißt wenn man nun contactPoints.Add macht würde Logger.contactPoints nicht mehr sich ändern. Ich wiederhole, ist hier in dem Beispiel aber ok. Ich hab trotzdem das mal abgeändert und auch Clean-Code-Prinzip eingebaut. using System.Collections; using System.Collections.Generic; using UnityEngine; public class DrawCollider2D : MonoBehaviour { private List<Vector3> contactPoints = new List<Vector3>(); private List<Vector3> normalPoints = new List<Vector3>(); void OnCollisionEnter2D(Collision2D collision) { contactPoints.Clear(); normalPoints.Clear(); ContactPoint2D[] contactPoint2d = collision.contacts; foreach (ContactPoint2D contactPoint in contactPoint2d) { contactPoints.Add(contactPoint.point); normalPoints.Add(contactPoint.normal); } } void OnDrawGizmosSelected() { if (contactPoints.Count > 0) { Gizmos.color = Color.blue; foreach (Vector3 contactPoint in contactPoints) { Gizmos.DrawWireSphere(contactPoint, 0.02f); } } if (normalPoints.Count > 1) { Gizmos.color = Color.red; int i = 0; foreach (Vector3 normalPoint in normalPoints) { Gizmos.DrawLine(contactPoints[i], contactPoints[i] + normalPoint); i++; } } } } Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
STU Geschrieben 26. Februar 2021 Autor Melden Share Geschrieben 26. Februar 2021 Hi zusammen, ich hätte doch zu diesem Thema nochmal eine Frage. Ich lese hier immer die Kontaktpunkte von dem anderen Objekt aus. Kann ich das auch umdrehen und mir den Punkt ausgeben von dem Objekt welches das Skript hat? Danke Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 26. Februar 2021 Melden Share Geschrieben 26. Februar 2021 Der Witz an Kontaktpunkten ist doch aber, dass sie genau gleich für beide beteiligten Objekte sind? 🤔 Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
STU Geschrieben 28. Februar 2021 Autor Melden Share Geschrieben 28. Februar 2021 Guten Morgen, ja schon. Mich würde in diesem Fall aber auch mehr der Kontakt am Collider interessieren. Ich würde gerne wissen wo das GameObject selbst getroffen worden ist. Also seitlich ober oben. Dies bekomme ich aber nicht von "meinem Objekt" sondern von dem getroffenen Objekt. Vector2 newColliderContact = new Vector2(collision.contacts[0].normal.x, collision.contacts[0].normal.y); Debug.Log ("newColliderContact: " + newColliderContact); if (newColliderContact.y > -0.5f) {... Danke Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
MaZy Geschrieben 28. Februar 2021 Melden Share Geschrieben 28. Februar 2021 Ich würde es nicht so kompliziert machen und EdgeCollider benutzen. Danach hat man ja pro Seite ein Collider. Geht natürlich auch mit BoxCollider pro Seite. EDIT: Huch hab gesehen hab schon mal hier geantwortet und nicht bemerkt, dass es ein alter Post ist . Dieser Post kann gelöscht werden. Kann leider nicht selbst tun. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 28. Februar 2021 Melden Share Geschrieben 28. Februar 2021 vor 10 Stunden schrieb STU: Ich würde gerne wissen wo das GameObject selbst getroffen worden ist. Also seitlich ober oben. Dies bekomme ich aber nicht von "meinem Objekt" sondern von dem getroffenen Objekt. Wie gesagt... Kontaktpunkte sind da, wo beide Collider sich berühren. Alle Kontaktpunkte liegen damit gleichermaßen auf beiden Collidern. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
STU Geschrieben 4. März 2021 Autor Melden Share Geschrieben 4. März 2021 nehmen wir an dass ich mit meinem Spieler auf einen Gegner Spring, dann wird beim Spieler der Collider unten angesprochen werden und wenn das Skipt im GameObjekt vom Gegner hängt würde doch dieser Fall stimmen, oder? newCollider.Contact.y == -1 Und jetzt meine Frage: Wenn ich im demselben Skript gerne wissen würde, wo der Collider vom GameObjekt selbst angesprochen wurde (also in diesem Fall oben +1) wie kann ich das abfragen? Danke Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Sascha Geschrieben 5. März 2021 Melden Share Geschrieben 5. März 2021 vor 13 Stunden schrieb STU: würde doch dieser Fall stimmen, oder? newCollider.Contact.y == -1 Nö. Kontaktpunkt sind in World Space und nicht relativ zu den Collidern. Heißt: Wenn deine Charaktere irgendwo um (1000,1000,1000) rumdüsen, dann wird er Kontaktpunkt auch irgendwo in dieser Gegend sein. vor 13 Stunden schrieb STU: Und jetzt meine Frage: Wenn ich im demselben Skript gerne wissen würde, wo der Collider vom GameObjekt selbst angesprochen wurde (also in diesem Fall oben +1) wie kann ich das abfragen? Bin mir nicht sicher, was du meinst, aber OnCollisionEnter und seine Freunde werden immer auf allen Komponenten von beiden beteiligten GameObjects aufgerufen. Link zu diesem Kommentar Auf anderen Seiten teilen More sharing options...
Recommended Posts
Archiviert
Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.