Jump to content
Unity Insider Forum

Physics2D.Raycast Problem


Lennard

Recommended Posts

Hallo,

Ich bin noch ziemlich neu in der Welt von Unity3D und bin gerade dabei einen Pong Klon zubauen.  Aktuell bin ich dabei das abprallen des Balls vom Spielerpad zu implementieren und zwar so, das je weiter außen der Ball gegen den Spieler stößt dieser in einem steileren Winkel abprallt. Ich habe mir dafür aus dem Netz ein Script gezogen und angepasst. Prinzipiell funktionier das schon, allerdings prallt er immer in einem 45° Winkel ab, auch wenn er mittig gegen den Spieler prallt. 

Nun habe ich die Vermutung das es an meinem Raycast des Spielerpads liegt, da dieser immer (0.0) zurück gibt. Noch zu erwähnen ist das ich Pong als 3D-Spiel entwickle. (Nicht nötig, habe allerdings so angefangen und konnte mich noch nicht dazu bewegen es als 2D Spiel zu entwickeln)

Hier mein angepasstes Script:

public class BallPhysics : MonoBehaviour
{
    public bool debugMode = false;

    //Wird bei einer kollision mit einem GameObject ausgeführt
    private void OnCollisionEnter(Collision collision)
    {
        //Wenn mit einem GameObject mit dem Tag "Player" kollidiert wird, dann...
        if (collision.gameObject.tag == "Player")
        {
            //Folgender Anleitung gefolgt: https://answers.unity.com/questions/880103/vector-based-pong-ball-bounce-calculations.html
            //-----------------------------------------------------------------------------------------------------------------------
            //Schreibe das kollidierte GameObject (Player) nach player
            GameObject player = collision.gameObject;
            //Schreibt die normalisierte velocity des Balls nach v
            Vector2 v = GetComponent<Rigidbody>().velocity.normalized;
            //Debug.Log("Velocity des Balls (v): " + v);
            //Dot Produkt zweier Vectoren
            float dotOfvn = Vector2.Dot(v,(Vector2)transform.right);
            //Debug.Log("Dot Produkt von v, transform.right (dotOfvn): " + dotOfvn);
            //Neuer Vector für die abprall richtung
            Vector2 R = new Vector3();
            //Fügt den Effekt des Wandabpralls zu R hinzu (Der Ball prallt immer noch gerade ab!)
            //transform.right = 0,1,0
            R += -2 * dotOfvn * (Vector2)transform.right + v;
            //Debug.Log("R = -2 * dotOfvn * transform.right + v");
            //Debug.Log("R bei Wandabprall gerade: " + R);

            //Hier irgendwo ist der Fehler, egal wo der Ball den Spieler trifft, hit bzw. hit.point ist immer (0,0)
            //--------------------------------------------------------------------------------------------------------------------------------
            //Es wird mit einem Raycast geprüft wo der Ball den Spieler getroffen hat.
            Vector2 v2 = new Vector2();                 //Nicht unbedingt nötig, war nur ein Versuch zur Fehlersuche
            v2 = GetComponent<Rigidbody>().velocity;    //Nicht unbedingt nötig, war nur ein Versuch zur Fehlersuche
            RaycastHit2D hit = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y), v2);
            Debug.Log("Ball Velocity bei Raycast: " + v2);
            //Vector vom Trefferpunkt des Balls auf dem Spieler zur mitte des Spielers
            Vector2 vectorFromHitPointToPadCenter = hit.point + (Vector2)transform.position;
            Debug.Log("Raycast Hit.point:" + hit.point);
            //--------------------------------------------------------------------------------------------------------------------------------

            //Die Länge zwischen dem Trefferpunkt des Balls und der mitte des Spielers
            //transform.up = 0,-1,0
            float lenght = Vector2.Dot(vectorFromHitPointToPadCenter, transform.up);
            //Holt die Länge des GameObject Players
            //Vector3 playerSize = player.GetComponent<Renderer>().bounds.max;
            float playerSize = player.GetComponent<CapsuleCollider>().height + player.GetComponent<CapsuleCollider>().radius*2;
            //Die Hälfte der Länge des Players
            //float halfCurrentPadWidth = playerSize.magnitude / 2;
            float halfCurrentPadWidth = playerSize / 2;
            //Gibt den den Abstand von der Mitte des Spielers zum Trefferpunkt des Balls in einer Gleitkommazahl an:
            //Dabei entspricht 1.0f = 100% & -1.0f = -100%.
            //Ein Positiver Wert beduetet der Ball oberhalb der Mitte des Spielers aufgetroffen, ein negativer unterhalb
            var percentageOfLenghtVSHalfPadLenght = lenght / halfCurrentPadWidth;
            //Die Funktion um einen Interpolierten Vector zweier 2D-Vectoren zu erhalten lautet:
            //A*t + (1-t)*B (transform.up = 0,-1,0 | transform.right = 0,1,0)
            R += (Vector2)transform.up * percentageOfLenghtVSHalfPadLenght + (1 - percentageOfLenghtVSHalfPadLenght) * (Vector2)transform.right;
            //Den Interpolierten Vector Normalisieren
            R.Normalize();
            //Die Geschwindigkeit mit der der Ball auf den Spieler getroffen ist, dem Ball in die abprallrichtung mit geben
            GetComponent<Rigidbody>().velocity = R * (GetComponent<Rigidbody>().velocity.magnitude);

            if(debugMode)
            {
                //Ausgabe zum Debuggen:
                Debug.Log("Halbe länge des Spielers: " + halfCurrentPadWidth);               
                Debug.Log("Abstand zur Mitte des Spielers: " + lenght);
                Debug.Log("Abstand zur Mitte des Spielers in %: " + percentageOfLenghtVSHalfPadLenght);
                Debug.Log("Abprall Vector R: transform.up * Abstand zur Mitte des Spielers in % + (1-Abstand zur Mitte des Spielers in %) * transform.right = R");
                Debug.Log("Abprall Vector R: " + (Vector2)transform.up + "*" + percentageOfLenghtVSHalfPadLenght + "+ (1 - " + percentageOfLenghtVSHalfPadLenght + ")" + "*" + (Vector2)transform.right + "=" + R);
                //Debug.Log("Abprall Vector R: " + R);
                Debug.Log("Ball Velocity bei aufschlag: " + GetComponent<Rigidbody>().velocity.magnitude);
                Debug.Log("Ball Velocity nach abprall: " + GetComponent<Rigidbody>().velocity);
            }
            

        }

    }
}

Wenn ihr Ideen oder Tipps habt, wäre ich sehr dankbar.

Mit freundlichen Grüßen

Lennard

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 2 Stunden schrieb Lennard:

Noch zu erwähnen ist das ich Pong als 3D-Spiel entwickle.

Meinst du damit 3D-Gameplay oder einfach 3D-Grafik? Es ist wichtig, hier zu unterscheiden. Wenn du 2D-Gameplay hast, dann solltest du auch 2D-Physik benutzen, unabhängig davon, ob deine Grafik aus 3D-Objekten besteht. Und dann ist wichtig, dass du bei deiner Physik-Variante bleibst. In deinem Script sieht man, dass du Rigidbody und OnCollisionEnter benutzt. Die sind beide (im Gegensatz zu Rigidbody2D und OnCollisionEnter2D) ausschließlich für 3D-Physik, weswegen ich annehme, dass du 3D-Collider benutzt. Diese werden von Physics2D-Methoden (wie Raycast) komplett ignoriert. Die 2D- und die 3D-Physik von Unity sind zwei komplett unterschiedliche Engines, die keine Überschneidungspunkte haben und nicht miteinander interagieren können.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Lädt...
×
×
  • Neu erstellen...