Wie kann man Ziele entsprechend dem Collider und seiner Koordinate richtig aufspießen und stapeln?

7

Ich mache ein anderes einfaches Spiel, ein Fangspiel, bei dem ein laichendes Zielspielobjekt mit einem Spieß erfasst werden muss, um es aufzuspießen. Hier wie:

  1. Zu Beginn fällt das fallende Objekt ( in Rot ) in vertikaler Richtung ( in Blau ). Geben Sie hier die Bildbeschreibung ein

  2. Bei richtiger Ausrichtung fällt das Ziel entlang der Spießlinie nach unten. ( in blau ) Dann wird ein anderes Ziel erzeugt und fällt vertikal. ( in rot ) Geben Sie hier die Bildbeschreibung ein

  3. Wenn das zweite Ziel in einer Serie erneut erfolgreich abgezielt wird, fällt es entlang des Spießes und wird gestapelt. Gleicher Vorgang immer und immer wieder, wenn ein anderes Ziel erzeugt wird. Geben Sie hier die Bildbeschreibung ein

Wenn ich es jedoch auf der Registerkarte "Szene" in Unity teste und mehrere Ziele aufspieße, wird es anstelle eines reibungslosen Ablaufs und Stapelns überlagert, anstatt es wie ein Pfannkuchen zu stapeln. So sieht es aus: Geben Sie hier die Bildbeschreibung ein

Wie ich bemerkte, als ich die Hälfte meines Fortschritts erreicht hatte, versuchte ich herauszufinden, wie ich mit Kolliderkörpern umgehen sollte, ohne mich gegenseitig zu verkleben, so dass sie sich tatsächlich wie im Beispiel des Bildes bei Nr. 1 stapeln. 3. Hier ist der Skriptcode, den ich im Zielspielobjekt hinzugefügt habe:

using UnityEngine;
using System.Collections;

public class ImpaleStateTest : MonoBehaviour {

    public GameObject target;
    public GameObject skewer;

    public bool drag = false;

    private float stack;
    private float impaleCount;

    void Start () {
        stack = 0;
        impaleCount = 0;
    }

    void Update () {
        if(drag) {
            target.transform.position = new Vector3 (DragTest.dir.transform.position.x, DragTest.dir.transform.position.y - 0.35f, 0);
            target.transform.rotation = DragTest.degrees;
            target.rigidbody2D.fixedAngle = true;
            target.rigidbody2D.isKinematic = true;
            target.rigidbody2D.gravityScale = 0;

            if(Input.GetMouseButton(0)) {
                Debug.Log ("Skewer: " + DragTest.dir.transform.position.x);
                Debug.Log ("Target: " + target.transform.position.x);
            }
        }
    }

    void OnTriggerEnter2D(Collider2D collider) {
        impaleCount++;
        Debug.Log ("Impaled " + impaleCount + " time(s)!");
        drag = true;
        audio.Play ();
    }

}

Abgesehen davon bin ich mir nicht sicher, ob es richtig ist, aber die einzige Möglichkeit, die aufgespießten Ziele beim Ziehen des Spießes nach links oder rechts festzuhalten, besteht darin, nur die X-Koordinaten vom Spieß abzurufen. Gibt es noch etwas zu empfehlen, um dieses Verhalten so realistisch wie möglich zu verbessern? Bitte helfen Sie.

David Dimalanta
quelle

Antworten:

1

Sie verwenden OnTriggerEnter2D, also verwenden Sie vermutlich Trigger anstelle von Collidern. Trigger werden nicht durch Kollisionen im Gegensatz zu Kollidern ausgelöst, sondern senden Nachrichten an Skripte und kollidierende Spielobjekte.

Wenn Sie also möchten, dass Ihre "Kreise" kollidieren, sollten Sie sie nicht auslösen.

S. Tarık Çetin
quelle
0

Stapelproblem

In Bezug auf das Stapelproblem bin ich mir nicht sicher, wie Ihre Klasse eingerichtet ist, aber ich würde in Betracht ziehen, die Positionierung der gestapelten Elemente basierend auf einem indizierten Ansatz zu handhaben.

Zum Beispiel (Pseudocode):

class Skewer : MonoBehaviour
{
   public List<SkewerElements> skewerElements = new List<SkewerElements>();
   public float skewerElementHeight = 1; // 

   public void UpdateSkewerPositions()
   {
       int count = skewerElements.Count; 
       float yOffset = count * skewerElementHeight; // use an offset to start

       for(int i = 0; i < count; i++)
       {
           // Basically by manipulating the yOffset you can "stack" elements based on the count of elements.
           skewerElements[i].transform.position = new Vector3(transform.position.x, transform.position.y + (-yOffset + (skewerElementHeight * i)), 0);
       }
   }
}

Ich habe ein negatives yOffset verwendet, denn wenn der Spieß y 0 ist, bewegen wir das erste Element um die Anzahl der skewerElements nach unten. Dann erhöhen wir das y um den Index des Elements um seine Höhe.

Devon Klompmaker
quelle
0

Abgesehen von den Motoren ist die Kreiskollision unglaublich einfach zu programmieren - Sie können dies von Grund auf neu tun. Jedes Kreisobjekt muss einen Vec2d-Positionswert und einen Radius haben.

Durchlaufen Sie in Ihrer Aktualisierungsschleife Ihre Liste aller Kreise und testen Sie dann, ob ein Pos-Wert von eins,> = die Position eines anderen, + beide Radien.

Wenn dies zutrifft, verhindern Sie, dass die Schwerkraft auf die sich berührenden Kreise wirkt. Oder Sie können eine Abstoßungskraft für das sich bewegende Objekt implementieren. Wohlgemerkt, wenn die beiden Kräfte (Schwerkraft und Abwehr) einen Unterschied von weniger als 1 haben, müssen Sie beide auf Null setzen, sonst vibrieren sie.

Sie benötigen hierfür eine Vec2d-Bibliothek, es sei denn, Sie möchten die Vektormathematik selbst ausführen (es ist nicht so schwer).

Was den Spieß betrifft: Da die einzigen Kräfte, mit denen Sie zu tun haben, Schwerkraft und Kollision sind, müssen Sie sich keine Gedanken über komplizierte Physik machen. Der Spieß ist eine Linie, sodass Sie die Kollision testen können, indem Sie feststellen, ob einer der Kreise x oder y> = die Spießposition ist.

Dies sollte alles ziemlich einfach sein, kommentieren Sie, wenn Sie Details benötigen.

bigcodeszzer
quelle