Hello all! I’m looking for some insight about a problem with collisions between bullets and enemies in a typical top view Shoot 'Em Up game, like Sky Force Reloaded.
In this kind of games you fly your aircraft or ship in a fixed x/y plane at a fixed height, the camera is positioned at a fixed angle and enemies comes to you from the air, at your height level, and the land below. The question is: **How do you check for collisions between your bullets and enemies below your height? **
In a 2D game there’s no problem but in 3D the heights of a tank, an enemy aircraft and your own aircraft are in real different positions, yet bullets flying parallel to the camera plane or the imaginary floor plane can hit a tank below you and an aircraft above or at your same height, never changing angles. The same for enemy bullets against your aircraft.
The possible solutions i found so far are:
Make the bullets collider shape vertically bigger so they can touch objects above/below their position. But this generates problems with the camera perspective since the visible bullet seems to collide at offset.
Use some Raytrace method to check for objects above/below the bullet movement plane. This is probably the way to go but it still could lead to offset collision perceptions.
Somehow spawn the bullets in some kind of layer that can check for collisions in **Screen Space. **This method seems to be used by **Sky Force **but i don’t know for sure.
Someone found a solution for this kind of collisions in top view perspectives? This is driving me crazy.
@Hillstrom If I’m getting this right, you mean your bullets reside in a plane, and the enemies may be in other planes ( geometric planes, I mean )?
If you want to trigger a collision when the bullet is actually above or below the enemy, then having an extended collision surface is correct. You can just have an invisible rod the extends both up and down from the bullet.
I’m not quite sure what you mean about the camera angle. If it’s really top down, then you wont be able to tell if the objects are in different planes. If you can see ‘into the planes’ from one side, then it’s not really top down…
Hello @ClockworkOcean thanks for answering!
The problem is actually that the camera is not fully top view but slightly (or not so slightly) pitched down, or at least, there’s some sense clear depth between the air plane (where aircrafts, ships moves) and the ground plane (where tanks, turrets, crates, etc resides). Since the game is 3D with a perspective camera, the elongated colliders on the bullets physically align correctly against objects but visually the bullet appears to hit objects before or after touching it, depending on where in the screen the bullet is colliding (this happens for the perspective more than a real camera pitch).
The other solution, to spawn all bullets on the same 3d plane height or layer, (the player’s plane so to speak), could work but there’s more obvious perspective discrepancies this way, specially at the moment were the bullet is fired from the tip of enemies cannons.
To maybe alleviate the complexity of all this, in my game the player don’t shoot bullets, it just need to evade enemy bullets. The player flies at a fixed height and enemies shoot at him from the ground or his same “aerial” height.
I leave a screenshot to show the problem i’m facing.
Maybe i can rotate the elongated collider to compensate the camera perspective? My head is about to explode, maybe i’m overcomplicating things…
@Hillstrom When I look at a vid of sky force it’s apparent that the enemy fire is being spawned in the player plane, and the player fire is spawned in the enemy plane.
I will think about this a bit more and take a closer look at you pic…
@Hillstrom I’m a little confused as your pic looks like a pic from skyforce
Are you using the same rocks? It looks like a Dimirtriy Dryzhak asset.
Anyway, sky force looks very 2D, camera is right above, so no problem.
I think if you want to have different planes and the camera to one side ( so to speak ), you’re going to have to migrate the ammo from one layer to another. Not very difficult, you know where you’re firing from and where the target is, then you can just get the vector between the two. ( get unit direction, and multiple by speed and delta time from tick ).
So your code, as it is now, but just make a tweak to the ammo movement so it can migrate between planes.
@ClockworkOcean The pic is actually from Skyforce. It was an example of the situation with the bullets collision heights.
I used that game as an example because it shows (and solves) exactly my problem. My game is mostly the same, camera at a fixed angle, very top down, no rotations no pitch changes. The player fly at a constant height above the ground… The construction is mostly the same.
I’m looking into the possibility that some bullets (the glowing bullet hell, not missiles) ar spawned at a fixed layer, maybe above the player, and moved in Screen Position checking collisions via raycast to anything below. Something like the mouse cursor do. Every bullet is like a mouse cursor moving at a fixed x/y plane and the collisions are checked like the mouse cursor position is checked against the world position with raycasts (raycast could be replaced by the longer collider).
Has this any sense? For a fixed camera angle it may work. I’m trying to think this as a regular 2D game but cheating the mind with visuals in 3D is way harder.
@Hillstrom It sounds like you’ve thought about it more than me, mouse type collision if defintely a possibility. I guess you could always ACTUALLY do it in 2D also
I have to bump this threat since I encounter the exact same problem as discribed. Very cool to see Hillstrom analyzed it the EXACT same way as I did. I’m also basing my assumptions off of Skyforce. They clearly tackled this issue in a smart way. Probably screenspace or depth buffer, i’m not sure. I don’t have much experience with programming or any other game engines. I really don’t want to go back to 2d for my game even if it fits the artstyle perfectly (My game is heavily inspired by Xenon2 megablast), I have sleepless nights over this
Anyway, did you eventually come up with a solution to this problem?