Problem with Object Pooling

My question got a little messy over time. For future reference (if anybody ever needs it) here is a short summary:

The symptom: The bullets get instantiated as they should when I start the scene. The bullets fly into the direction they are shot and after leaving the screen (and therefore also leaving a trigger) they get disabled and moved back to the object pool.
If a bullet hits an enemy it also gets pooled right away. If that exact bullet is retrieved however it only flies for about half the screen before disappearing. They apparently get pooled for no good reason. I checked wether they collide with anything (they don’t) or wether they are not actually pooled but destroyed for some reason (also a no). So they get pooled after a few seconds even though I didn’t call the Pool() method. There is no timer involved or anything that would cause any delayed pooling.
Anyways, these bullets that disappear get moved to the pool again. If they get retrieved a third time they disappear again and so on and so forth. After a few (seamingly random) times of disappearing the bullets behave normally again until they hit an enemy.

The problem: When a bullet hit an enemy the single bullet was (don’t know why) added to the array of pooled objects multiple times. So the bullets that have already been shot were still inside the array (at least one entry) and have been reused even though they were already retrieved.

The solution: As @DerDude87 pointed out correctly, I should have checked wether the object has already been added to the array of pooled objects before adding it. Thanks to everyone, thanks DerDude87, for helping me find the solution. Turns out it was something as simple as this to fix my problem.

One thing you could do is make sure each object can only be in the pool list once. Having one object referenced multiple times in the pool list could very well cause the behavior you are describing.

Maybe check in the inspector and see if the list grows larger as time goes by.

Then, to fix this issue, you could make sure to not add the object twice with:

if(!pooledObjects*.Contains(obj))*

pooledObjects*.Add(obj);*
This could happen when your projectile hits multiple colliders in the same frame. Setting the object inactive will only take effect on the next physics-frame. You cannot rely on OnTriggerEnter to be called only once.

I dont know if you attached a 2d collider on the bullet or 3D but here are some info that might be useful:

I guess u already know that for any kind of OnTriggerEnter/OnCollisionEnter function {2D or 3D} u need colliders attached to both of them and rigidbody to any one of them.

3D collision:

  1. Both should have 3D colliders. The one having the trigger/collision script should have isTrigger enabled.

2D collision:

  1. Both should have 2D collider. The one having the trigger/collision script should have isTrigger enabled.

  2. The one having rigidbody should have simulated as checked. I u dont want to use gravity, use BodyType as kinematic.

3D+2D collision

  1. No inbuilt method in unity. Reason is that for 3D unity uses PhysX and for 2D it uses Box2D

  2. Workaround: Attach an empty 3D box collider to the 2D object you want to detect.If its not possible to attach directly to the gameObject, attach it as a child.

There’s two things that very confusing about how you are pooling objects. A pooling script should be pretty straight forward to be honest. The only things it has to do are: disable objects, store them, and retrieve next pooled object or create one if there’s none available.

Confusing thing one:
Your pool method is storing objects only if it finds their name to be equal to some other object’s name in the objectPrefabs array/list. I’m not sure why you’re having to do this since it shouldn’t be necessary for object pooling. What happens if the name doesn’t equal anything in the objectPrefabs? Are you potentially pooling other types of objects in combination with bullets? You’re also storing the bullets under some container parent but never actually moving the object to the container. If you’re trying to move the bullets to some location you could just set the position of the bullet to the position of the container (unless the container moves around).

Confusing thing two:
When you are trying to pull objects from the object pool you again compare names. This is even more confusing as it looks like a different container than the one you used when pooling the object. Also, not all code paths return an object, which would obviously cause strange behavior. You need to make sure your object pool can always return an object, whether it is an already pooled object or one it has to instantiate.

I bet the problem is related to a mismatch/discrepancy between the name comparison of when you pool the object vs when you retrieve the pooled object. To help you debug that I would add some logging to all possible paths of both for loops.

Edit:
Apparently you posted something while I was writing this up. With the behavior you described it sounds like the bullets are not removed from the pool container, and are therefore reused prematurely when you try and fire a new bullet. This is exactly what happens in my example if you comment out the line that removes the object from the list when it is retrieved.