Object Reflecting off a Wall

Hey everyone! I’m trying to make an object “bounce” off a wall when it collides with it. The object has a rigidbody component (gravity disabled), and a mesh collider. It is always moving on its z axis. I want it to be deflected off the wall just like in an old pong type of game, so not by the built in physics. Take a look at these images and it may become clear as to what I’m talking about:

474429--16672--$Rocket 1.png

474429--16671--$Rocket 2.png

I have no idea where to begin (I’m pretty new to unity) so any help is appreciated!

1 Like

adding a collider and a rigidbody should work on its own

use raycast from the bullet to find the normal of the surface that’s going to be hit

Basically if you have a vector v, which represents the object’s velocity, and a normalized normal vector n, which is perpendicular to the surface with which the object collides, then the new velocity v’ is given by the equation:

v’ = 2 * (v . n) * n - v;

Where ‘*’ is the scalar multiplication operator, ‘.’ is the dot product of two vectors, and ‘-’ is the subtraction operator for two vectors. v is reflected off of the surface, and gives a reflection vector v’ which is used as the new velocity of the object.

Or in the example you’ve given, the normal would be (0,-1,0) and if you bullet is traveling upwards at 45 degrees its velocity might be (-2,2,0) and after the reflection it’d be moving at (-2,-2,0)

But yeah, use colliders and rigid bodies and let the physics engine sort it out. To prevent an object moving on the z-axis you can either attach a physics joint to the object or you can just add a line in function FixedUpdate that sets the z position and velocity to 0. That’s very effective at forcing 2D movement. Also use primitive colliders (box, sphere etc) to make sure it’s not at an odd angle.

2 Likes

Thanks for helping! But I’m having a hard time putting that math into a script. Could you help me out?:face_with_spiral_eyes: Also, the physics engine won’t work because when the bullet hits the wall, it just slides to the side as it tries to continue to move forward.

In the Mesh collider in the Inspector try giving it a physic material Bouncy.

and if the rigidbody has freeze rotation enabled, turn it off

1 Like

Just wanted to say: This works great. It took me a bit to get it implemented correctly with my current code (had to reprogram how movement was working to be a Vector3 for velocity), but works great.

As a quick note for anyone trying to use it: I had to multiply the end result by -1 to make it translate correctly, don’t know why.

Here’s the code, in case anyone wants to try it out for yourself

var velocity : Vector3; //Our movement velocity
var speed : float; //Speed of object


function Awake()
{	
	velocity = this.transform.forward; //Placeholder default velocity // Change to whatever you need
	speed = 20;
}


function Update()
{
	this.transform.position += velocity * Time.deltaTime * speed; //Update our position based on our new-found velocity
}


function OnCollisionEnter( info : Collision ) //When we run into something
{
	//'Bounce' off surface
	for( var contact : ContactPoint in info.contacts ) //Find collision point
	{
		//Find the BOUNCE of the object
		velocity = 2 * ( Vector3.Dot( velocity, Vector3.Normalize( contact.normal ) ) ) * Vector3.Normalize( contact.normal ) - velocity; //Following formula  v' = 2 * (v . n) * n - v
		
		velocity *= -1; //Had to multiply everything by -1. Don't know why, but it was all backwards.
	}
}

I was searching around for a solution to do just what this solves… I like this solution, but I found it difficult to visualize the result using the dot product… so I came up with an intuitive solution. Basically, the result needed is a reaction to the impact on a surface normal. So, we need a reflection about the surface normal which is just flipping the velocity vector about the surface normal and correcting the sign to achieve the final solution. Let my solution explain itself rather than me making it more convoluted than it is:

function OnCollisionEnter( info : Collision ) //When we run into something
{
	//'Bounce' off surface
	for( var contact : ContactPoint in info.contacts ) //Find collision point
	{
		//Find the BOUNCE of the object
		velocity = Quaternion.AngleAxis(180, contact.normal) * transform.forward * -1;
	}
}
1 Like

i’m trying to do the same thing, but I am doing it in 2d.
So the solution scriptgeek gave doesnt work.
I get an error

I have my collision point.
Now I need to normalize it?

What if I reflect a ray perpendicular to the collision angle and move my object along that path?

From what i can see you can’t use .normal in 2d -Unity - Scripting API: RaycastHit.normal

Any advice would be great. I am completely stuck on this one.

void OnCollisionEnter2D (Collision2D col)
    {
        ContactPoint2D contact = col.contacts[0]; // logs the collision vector data in an array I believe
        c_collisionPoint = contact.point; // defines the collision data

        c_Velocity = Quaternion.AngleAxis(180, contact.normal) * transform.forward -1; "Operator'-' cannot be applied to operands of type 'UnityEngine.Vector3' and 'int'"
}
}
3 Likes

I believe this is how to subtract using Vector math…
( see: Unity - Scripting API: Vector3.operator - )

    void OnCollisionEnter2D (Collision2D col)
        {
            ContactPoint2D contact = col.contacts[0]; // logs the collision vector data in an array I believe
            c_collisionPoint = contact.point; // defines the collision data
 
            c_Velocity = Quaternion.AngleAxis(180, contact.normal) * transform.forward - new Vector3(-1.0f,-1.0f,-1.0f);
    }
    }

This post. Just orient the object using this and raycasting.

Bradford, you forgot the “*” (multiply) symbol after your transform.forward. It should read || transform.forward * -1 || At the moment you are subtracting 1 from transform.forward instead of multiplying.

Here is the link that helped me to understand and solve the problem I was facing regarding bounciness. Hope It will help you too.

nice