If you are using physics simulation, don't just change the Transform
of your object - this would most likely break the physics (but if you just use colliders as triggers, this might be OK).
If you use physics, you should move your ball with AddForce
. But here you could encounter various problems. The first problem is keeping the speed constant. You could specify max bounciness to the ball physics material and then call AddForce
only when the ball changes the direction it moves (you also could just try to change the already applied velocity). Another option is to do AddForce
with the ForceMode.VelocityChnage
and specify to it the difference between current and desired velocities on each frame. Unfortunately this is not implemented for 2D physics, but some guys in Unity forums created the exetension method for that. There is also an easier way: you could just AddForce
on each frame, but right after you could clamp the velocity by using _rigidbody.velocity = Vecotr2.ClampMagnitude(_rigidbody.velocity, Mathf.Abs(_maxSpeed));
. This, btw, could break the physics a bit, since you're changing the velocity
directly.
You also should take care about the global treshold values in Edit->Project Settings->Physics 2D
. But as you could see there is no Bounce Treshold
value for 2D physics (there is for 3D). This means that when the ball will collide with a collider under a very small angle, it will "stick" to the collider and you have no option to control it - it is just hardcoded into physics settings (that problem 100% was in 4.6, not sure about Unity 5). So you should check that there is no such problem in your game.
Another problem appears, when your ball is moving too fast. This is pretty much similar to what you are getting right now: the ball may pass through the colliders. Physics in Unity is calculated in FixedUpdated
. FixedUpdate
is invoked each 0.02 seconds (you could see and change this value in Edit->Project Settings->Time
). If the ball moves too fast it could pass through the collider between frames - and then there is no collision. You could try to adjust the Interpolate
and Collision Detection
settings of your Rigidbody2D
(the same for 3D), but this would not help if you move your object via Transform
- physics can't predict such a movement. You should move with physics. But, if changing those values doesn't help you, then you have the last resort option to use raycasting. There is a special script called DontGoThroughThings in Unity wiki, which does it for you. You only would need to convert it to 2D (or find it somewhere, I am pretty much sure someone already did it).
You could try to move your ball only by using Rigidbody2D.velocity
. This may work, but may not. Velocity is physics, that's true, but changing it manually may break the physics calculations again. Most likely this would be seen when the ball will hit the other moving objects with "normal" physics. Another problem could be gravity. This happens because when you change the value manually, you remove the forces that were just applied to the object, and it will behave unnaturally. So you need to try it and see if it works the way you want. There is a probability that you can't go with it.
Controlling the physics yourself manually (by checking collisions manually in scripts by using positions and sizes of the objects) is not an option for games with many moving objects (because there is really a lot of work), but could be used for simple games like an arkanoid. Manual collisions in 2D aren't that difficult, but there are some problems to solve. The two most important are collisions with edges and collisions with moving objects.
I hope that you now have a bit better understanding on the subject. I'm not sure what exactly to recommend in your case, but you could try some (or all) of the options described above. I only hope you wouldn't need to write your own physics engine.