- Home /
Some collisions in 2D are not detected, how can I get them all detected?
Hi, I am making a game and I have a lot of it done. When I shoot and hit an enemy they die, but some hits are not detected so the enemy remains alive. Assume the health is 30.
In update I have
if (Enemy_Health <= 0)
Destroy(gameObject);
in void OnCollisionEnter2D(Collision2D coll)I have
if (coll.gameObject.tag == "Bomb")
Enemy_Health = Enemy_Health - 30;
if (coll.gameObject.tag == "Bullet")
Enemy_Health = Enemy_Health - 30;
The bullet has a rigidbody and a box collider. While the enemies have polygon colliders(I have also tested box colliders, but not rigidbody as I have an invisible wall to prevent the player from leaving, which prevents the enemies from entering from off screen).
The code works fine but some of the collisions are not detected and thus an enemy that would die in one hit sometimes dies in 3-5hits. Could someone please help me find a solution or find any mistake in this code. Thanks.
Also in case it helps these enemies are being instantiated from another location/script(moving left) and are being destroyed if they exit the screen left. This is also being done for backgrounds(clouds, ground etc).
I also think coll.gameObject.tag == "Bomb/Bullet" might be the problem as maybe the tag is sometimes not read properly.
Answer by drex150 · Aug 03, 2014 at 02:40 AM
I think the reason this is happening is because collision is being calculated every frame. If you are shooting physical objects, and they go fast enough, between the current frame and the next frame, it could travel past the collision all together.
Basically, you're bullets are shooting so fast that on this frame, it is about to hit the collision and in the next frame it is well past the collision so there was never any time when they actually touched each other.
Instead of using physics to control your bullets, you should use a raycast. There's lots of reasons, but one of the main reasons is that raycast will not ever miss what it touches. The second biggest reason is that instantiating a bunch of little bullets is way more resource intensive than using a ray. You can probably keep your bomb as it is, but I'd suggest changing how your bullets shoot.
EDIT: Just noticed you said 2D so use this instead: http://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html
Thanks for the reply. I tried to shoot one bullet every 1-2secs but some of those bullets still don't kill the enemy(all bullets hit the enemy and disappear), so I'm thinking it might not be the case of rapid fire. I'll look into rays for the bullet, but it does the same thing for bombs. According to your reply if a bullet is destroyed to soon after it has appeared, would it not register a collision as well? If you have any other suggestions for the bombs I'd appreciate it.
It is not the rate of fire, but the speed of the bullet that his the issue. There is no complete fix for this problem, but there are a variety of things that can be done that usually fix it for specific situations. The one that has the most impact is to reduce the fixedTimestep.
Edit > Project Settings > Time
Reduce Fixed Timestep from it default of 0.02 to 0.01. Note that reducing this value means more cycles will be devoted to physics calculations. Search UA for other things that can be done.
Ok I'll try and reduce the bullet speed and time step and see if either fixes the problem.
@bokharij Sorry, I worded that a bit wrong. It's not the rate of fire, it's the actual speed the bullet travels that is the problem. The bullet is moving through the air so fast that it's passing the collision before it ever has a chance to say it is colliding. Are you sure that the bullets are actually hitting the monster and disappearing after it hits the monster?
@robertbu brought up the Fixed Timestep, which does definitely help with collision issues like this. The problem with that, as he said is that it will calculate physics more often. This means the game will take more processing power to run.
The advantages of rays are that you don't have to deal with physics at all. You simply cast the ray, if an enemy is in the ray when you shoot, it takes damage. No need to physically shoot a projectile across the level. I'm using a ray for my FPS game I'm making and it's definitely the way to go for guns that shoot bullets that travel extremely fast (like basically every real world gun).
Ok I got it to work. The problem seemed to be that the bullet was destroying itself(collision detection) at the same time the enemy was doing a collision detection. To fix it I made the enemy destroy the bullet ins$$anonymous$$d. For the bomb I made the enemy use a method from the bombs script(that destroys it). Both ways work. Thanks for all of your help. Hope this solution helps in the future.
Your answer