# Object Reflecting off a Wall

Discussion in 'Scripting' started by CgRobot, Jan 16, 2011.

1. ### CgRobot

Joined:
Jan 4, 2011
Posts:
175
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:

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

shley92822212 likes this.
2. ### Mike L

Joined:
Sep 14, 2010
Posts:
1,035
adding a collider and a rigidbody should work on its own

3. ### spinaljack

Joined:
Mar 18, 2010
Posts:
881
use raycast from the bullet to find the normal of the surface that's going to be hit

http://unity3d.com/support/documentation/ScriptReference/RaycastHit-normal.html

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.

Last edited: Jan 16, 2011
4. ### CgRobot

Joined:
Jan 4, 2011
Posts:
175
Thanks for helping! But I'm having a hard time putting that math into a script. Could you help me out? 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.

5. ### celinscak

Joined:
May 4, 2010
Posts:
102
In the Mesh collider in the Inspector try giving it a physic material Bouncy.

6. ### Mike L

Joined:
Sep 14, 2010
Posts:
1,035
and if the rigidbody has freeze rotation enabled, turn it off

7. ### Loftless

Joined:
Mar 20, 2011
Posts:
16
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
Code (csharp):
1.
2. var velocity : Vector3; //Our movement velocity
3. var speed : float; //Speed of object
4.
5.
6. function Awake()
7. {
8.     velocity = this.transform.forward; //Placeholder default velocity // Change to whatever you need
9.     speed = 20;
10. }
11.
12.
13. function Update()
14. {
15.     this.transform.position += velocity * Time.deltaTime * speed; //Update our position based on our new-found velocity
16. }
17.
18.
19. function OnCollisionEnter( info : Collision ) //When we run into something
20. {
21.     //'Bounce' off surface
22.     for( var contact : ContactPoint in info.contacts ) //Find collision point
23.     {
24.         //Find the BOUNCE of the object
25.         velocity = 2 * ( Vector3.Dot( velocity, Vector3.Normalize( contact.normal ) ) ) * Vector3.Normalize( contact.normal ) - velocity; //Following formula  v' = 2 * (v . n) * n - v
26.
27.         velocity *= -1; //Had to multiply everything by -1. Don't know why, but it was all backwards.
28.     }
29. }
30.

8. ### ScriptGeek

Joined:
Mar 4, 2011
Posts:
44
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:

Code (csharp):
1.
2. function OnCollisionEnter( info : Collision ) //When we run into something
3. {
4.     //'Bounce' off surface
5.     for( var contact : ContactPoint in info.contacts ) //Find collision point
6.     {
7.         //Find the BOUNCE of the object
8.         velocity = Quaternion.AngleAxis(180, contact.normal) * transform.forward * -1;
9.     }
10. }
11.

Last edited: Feb 28, 2013

Joined:
Aug 12, 2013
Posts:
2
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 -http://docs.unity3d.com/ScriptReference/RaycastHit-normal.html

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

Code (CSharp):
1. void OnCollisionEnter2D (Collision2D col)
2.     {
3.         ContactPoint2D contact = col.contacts[0]; // logs the collision vector data in an array I believe
4.         c_collisionPoint = contact.point; // defines the collision data
5.
6.         c_Velocity = Quaternion.AngleAxis(180, contact.normal) * transform.forward -1; "Operator'-' cannot be applied to operands of type 'UnityEngine.Vector3' and 'int'"
7. }
8. }

Joined:
Dec 12, 2009
Posts:
372
11. ### LtKelleyUSMC

Joined:
Oct 6, 2012
Posts:
20
I believe this is how to subtract using Vector math...
( see: http://docs.unity3d.com/ScriptReference/Vector3-operator_subtract.html )
Code (CSharp):
1.     void OnCollisionEnter2D (Collision2D col)
2.         {
3.             ContactPoint2D contact = col.contacts[0]; // logs the collision vector data in an array I believe
4.             c_collisionPoint = contact.point; // defines the collision data
5.
6.             c_Velocity = Quaternion.AngleAxis(180, contact.normal) * transform.forward - new Vector3(-1.0f,-1.0f,-1.0f);
7.     }
8.     }
9.

Joined:
Aug 22, 2013
Posts:
356