3
\$\begingroup\$

I have my bouncing ball game. The ball bounces up when it hits the ground and when it hits the left wall it changes direction to right and when it hits the right wall it changes direction to left and continues to bounce. Now the problem is that sometimes physics system does not register the collision between the ball and left/right wall, so the ball just passes through them and goes out of play, I have no idea whats going on. I will attach two pictures, one from game view and other from scene view.enter image description here

enter image description here

Again I say everything works great, the ball bounces and hits the wall then changes the direction but sometimes the collision between a wall and a ball is not registered and the ball just passes through the wall like there is no physics and goes out of camera view.

\$\endgroup\$
1
  • \$\begingroup\$ What physics system are you using? \$\endgroup\$
    – Anko
    Commented Aug 27, 2015 at 17:24

1 Answer 1

1
\$\begingroup\$

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.

\$\endgroup\$
7
  • \$\begingroup\$ Thank you for your detailed explanation, I have a more clear vision of the problem now, I was not aware of those things, I was planing to use velocity but you said it may or may not work, and using add force forces me to change many things, and btw lol for the last statement about writing my own physics engine :D, I dont know what to do, the problem is that the game is already available on google play, people are downloading it and I need to do something about it, I will probably try using velocity to move the ball and in the mean time I'll try to fix it using add force and see how it goes \$\endgroup\$ Commented Apr 28, 2015 at 20:29
  • \$\begingroup\$ My problem is that I need to set the collider of the balls to be a trigger, and when I try to use add force and the collider is a trigger that is not working, if I use velocity that is working, if I uncheck is trigger for the collider then add force works but as you mentioned I have other problems that I need to fix, for example the ball is not moving the way it should be its like balancing in the air, its not moving constantly in one direction, but when using velocity it does all those things :S \$\endgroup\$ Commented Apr 28, 2015 at 20:54
  • \$\begingroup\$ @FahirM You're right, trying velocity first may be a good choice for you, because it works much similar to transform.position than the AddForce. You would just need to change less code, which is important if the game is already published. The problem with trigger could be easily fixed: add a child game object to your ball and place your trigger on it. The ball should have a normal collider. In that case you also might need to place that objects on different Layers and disable the collisions between some layers in Edit->Project Settings-> Physics 2D (the matrix at the bottom). \$\endgroup\$
    – Vladimir
    Commented Apr 29, 2015 at 8:57
  • \$\begingroup\$ When using AddForce you also might need to adjust the values on your rigidbodies, set the proper materials (with max bounciness for the ball) to colliders, switch off gravity etc. This requires some time to learn and try it all, but not that much. And I also remembered the other way to keep the velocity constant, use _rigidbody.velocity = Vecotr2.ClampMagnitude(_rigidbody.velocity, Mathf.Abs(_maxSpeed)); right after your AddForce. This, however, might break the physics too, but not that much than when applying the velocity directly without forces. \$\endgroup\$
    – Vladimir
    Commented Apr 29, 2015 at 9:17
  • \$\begingroup\$ What about setting the collision detection to continues? Because when I searched about the DontGoThroughThings script that you posted I found a post on unity forum talking about that, and one guy from unity mentioned that, that script was created before unity had collision detection continues on rigid body, which means that now that it has thats the same thing as that script. \$\endgroup\$ Commented Apr 29, 2015 at 10:01

Not the answer you're looking for? Browse other questions tagged .