I have a new question related to collision detection using casting.
In the image above, you can see the paddle and the ball of my game. I have added an offset to their colliders just to simulate the actual problem I am trying to solve.
The paddle collider is representing the casting I am using to detect a ball hit.
The ball collider represents the future position of the ball.
So the question this time is simple: is there any way to detect the future position of the ball using casting? Because if I don’t it this way, during the next frame the ball will overlap with the paddle and since I don’t want the queries to start inside the colliders, the collision will not be detected.
Of course, if there is some other way to tackle this problem, that would be great too!
Don’t you want to instead find the future position of your hall using physics? The collider doesn’t have anything to do with the position your trying to reference
You can either make it so that the paddle always moves before the ball or have the paddle notify the ball that it has hit the paddle. The ball will then need to backup and move and cast again to get the correct hit normal.
In 2D you can select if queries inside colliders return results or not, the option is in the 2D physics settings.
The solution does depend on what you’re not saying which is; is this just a paddle and multiple balls problem?
If so, performing any query individually will clearly not give you results about other objects as they’ve not moved so a solution is to have another unity scene which has its own local physics scene which contains a proxy for your paddle and however many balls you have and/or any static geometry if you’re interested in that being part of the simulation.
Add a proxy object in the scene for your paddle and balls. These don’t need visuals, they only need the physics components but keep a reference to them. Use the standard scene management stuff to do this by setting the unity scene as the active one then using: Unity - Scripting API: SceneManagement.SceneManager.SetActiveScene and then switching back to the original scene.
With all that set-up as a one-time thing at start-up you can do this when you want to check stuff:
Set the proxy paddle & balls to have the same Rigidbody2D.position & Rigidbody2D.rotation as the real paddle & balls. Don’t use Transforms, use the Rigidbody2D directly as you then don’t have to wait.
You’ll get callbacks from hits or you can perform the available queries on PhysicsScene2D if you need.
I would recommend that you turn-off simulation on your proxy Rigidbody2D when you’re finished: Unity - Scripting API: Rigidbody2D.simulated which will remove them from that simulation. The reason I say this is because you don’t want Exit callbacks when you move them next time. Next time you’ll need to enable these again.
The above sounds complex but it’s not, do it as a simple test in a test project and you’ll find that it’s super easy to set-up.
If it helps get your mind around it; when you run a simulation and add objects and do all sorts of things you’re used to doing in 2D physics, you’re doing the same but on the default PhysicsScene2D we create for you. Here you’re essentially creating your own.
Now there are other ways of doing this but it does depend on exactly what you need. For instance, you could simply position a CapsuleCollider2D for your paddle that represents it in a future time as well as capsules for the balls in their future time. Any overlaps means they’re going to hit and you can then focus on when they hit.
Wow, thank you very much for the explanation. I didn’t know anything about this.
Basically, my problem is just about the collision detection between the paddle and the ball. Let’s say I’m using two collision detections:
A cast from the ball position using its direction of motion to detect hits on walls, bricks and the surface of the paddle.
A cast from the paddle to detect ball hits on its sides, so I add the paddle velocity to the ball and push it until it moves away.
The only problem I have found is that sometimes the ball goes through the paddle as you can see in the following video:
The first hit is on the surface of the paddle and works fine.
The second hit goes through the surface of the blade and is not detected by any of the molds.
The third hit is a side hit so you can see that the paddle pushes the ball a bit, which is the expected behavior.
I am not able to understand why the second hit behaves like this, so my guess is what I shown in the following image:
I guess the ball position “calculated for the next frame” and the paddle cast overlap, so during the next frame the ball will be physically overlapped by the paddle and no collision will be detected as I have disabled the “start queries inside colliders” option because it gives me problems with collisions between the ball and the walls of my game (ball getting stuck forever on the wall due to another overlap when repositioning the ball…).
This happens only with one ball, but in the end it will happen with several. Anyway, although your explanation is interesting, and may be useful in the future, it seems to me a bit overkill for this problem, no?
Are you using set position to set the exact position of the ball? I think your solution here is probably just to make the paddle a little bit bigger. it looks like to me that the overlapping only occurs when the curved part of the paddle touches the ball. I would either do all of this with the built in unity physics or I would define the bounds of the paddle as NOT round and as pixels with square corners and edges and then change the outputting direction of the ball using math.
After testing all the alternatives you proposed, I ended up finding the solution that fits perfectly with my needs:
On the one hand I have decided to cast the future ball position and on the other hand I am doing two things with the paddle:
Modifying the offset of its collider in the same direction as the direction of motion of the paddle, in order to predict where the collision will occur.
Casting a CapsuleCollider2D from the current position of the paddle (no offset), so that in case the ball and the paddle overlap (meaning the ball will be hit on the side of the paddle), the ball will be pushed away from the paddle.
With this solution, everything works fine! Thank you very much for your help, guys!