2D bouncing formula doesn't work properly

2019-07-21 05:36发布

问题:

I am new to unity, and i am trying to create a bouncing ball, so i've did many researches about bouncing realted physics and i found a formula :

Formula:

-2*(V dot N)*N + V

Where V is the velocity vector and N is the normal of the surface on which the ball will bounce

Here is my script :

using UnityEngine;

using System.Collections;

public class BallPhysics : MonoBehaviour {



    void Start () {
        rigidbody2D.velocity =new Vector2 (-1,-3);

    }

    // Update is called once per frame
    void Update () {

    }
    void OnTriggerEnter2D(Collider2D col) {

        if (col.gameObject.name == "Pong") {
            tBounce ();
                }


    }

    void tBounce(){
        RaycastHit2D hit = Physics2D.Raycast (new Vector2 (transform.position.x,transform.position.y), new Vector2(-1f,-1f));
        Vector2 n = hit.normal;
        Vector2 v = rigidbody2D.velocity;
        Vector2 R = -2 * (Vector2.Dot (v, n)) * n + v;
        rigidbody2D.velocity = R;
    }
}

I am giving the ball a velocity vector in the start function, i am using OnTriggerEnter2D for collision handling and raycast2D to get the normal of a surface.

The problem is that the script doesn't reflect the velocity vector called R, i think the probleme is in the normal vector.

For example let's say V is a Vector2(-1,-1) so basically R should be (-1,1), but it's not. R is (3,1) !

i've successfuly been able to make a ball bouncing on Horizontal/vertical surface by reversing the ball velocity but this won't work properly with arbitary angles,that's why i am using this formula. So what's the problem ?

回答1:

Your raycast is likely hitting the wrong collider. You start it at transform.position. That is the center point of your ball object.

Imagine a ray coming out of a circle's center. What's the first line it hits? It hits the circle itself first. So your Raycast reports the surface normal of the ball, not the pong paddle.

There are many ways to get around this. You can apply a Physics Layer that ignores raycasts. I think there is one pre-defined like that. You can create custom ones as well and supply a layer mask to your raycast.

There are other ways to solve it like originating the raycast from somewhere else, but since you're doing this as the objects collide, a layer mask is probably the simplest.