I’ve been fiddling with object pooling lately.
I have: A gun that shoots. There are 2 scripts of importance attached. The others have nothing to do with any of this.
First one deals with shooting and giving the bullet direction and speed. Here’s the part where I get my bullet:
The second script attached is the one with a simple object pooling I’ve made:
public GameObject projectilePrefab;
List<GameObject> pooledProjectiles = new List<GameObject>();
void Start()// Add 1 projectile in the pool at the start
{
GameObject projectile = Instantiate(projectilePrefab);
pooledProjectiles.Add(projectile);
projectile.SetActive(false);
}
//Method to get projectiles from
public GameObject GetPooledProjectile()
{
//Check if there are any available projectiles
foreach (GameObject projectile in pooledProjectiles)
{
if (!projectile.activeInHierarchy)
{
return projectile;
}
}
// Create a new projectile if there aren't any
GameObject newProjectile = Instantiate(projectilePrefab);
pooledProjectiles.Add(newProjectile);
return newProjectile;
}
As for the bullet it only has a Sprite Renderer, Box collider switched to trigger, a RigidBody2D and this BulletScript which currently only has these 3 lines:
When the player spawns in my game scene. A few block away there’s a gun on the ground. I’ll go pick it up.
At that point I Instantiate a gun on my player. Which enables the object pooling and shooting scripts on the gun. I’ve checked and there is a bullet clone instantiated in the editors hierarchy. It is set inactive. All as planned. But when I press left mouse button nothing happens. The bullet stays inactive. Only on the consecutive button presses it starts shooting properly.
Since I’ve only made the pool size 1. It is reusing the same bullet over and over again. But if I start clicking faster and I need another bullet to be added to the pool. The same thing happens. It does not show. I had a theory that the bullet needs some time to initialize or something before I can use it. In an Active state.
So I’ve changed to code a bit and right after adding it to the pool I’ve waited 0.1 seconds before I’ve set it inactive. Unfortunately it didn’t help. The first bullet still didn’t show.
Also when I’m reusing bullets. It seems that sometimes I see the bullet whooshing by from it’s last position to the guns bullet start transform. Instead of teleporting. I’ve tried to execute it in Update or in FixedUpdate. It didn’t help. I thought setting transform.position was a teleportation move and not a super fast moving technique
I have went through some debugging before I’ve posted. Even tried asking chatgpt to help troubleshoot.
I’ve also tried the Debug.Logs. I’ve set a bunch of them in front of it and right after it as well. One was right after I set the bullet active and it still fired with no visible bullet on the scene. I didn’t know there was a Debug.Break() option I’ll try that.
But According to your post object pooling isn’t required for me. I guess I’ll just go back to instantiating things again.
Well at least I’ve learned some new things.
Update:
I’ve tried the Debug.Break(). Added it right after I set it active. And checked the bullet it was inactive. Then I thought maybe the invoke is the issue. When I instantiate the bullet it is active so it might just set off that invoke. Fixed the code to do it in a different way. Didn’t help.
I’ve also took a closer look on the bullet after the Debug.break. When I activated it manually in the inspector. The bullet was in the correct position and a correct rotation. So the only issue is that it’s not active.
So I’ve tried to set it active multiple times in a row. Well that was pointless
At least I’ve figure out my other issue. The whooshing was caused by the bullet trail I’ve added to the bullet. Normally it’s barely visible so I keep forgetting it’s there.
Well this was from your other posts:
Seriously, trust me, pooling objects can get really really complicated unless you are very disciplined about what objects get recycled and what state they have.
You will need to maintain and debug and grow that reset code for EVERY different flavor of thing in play now, plus EVERY NEW THING forever into the future if it is on a pooled object.
And in the end… oh look, it isn’t even any faster anyway because Unity3D is already a beast of an engine!
For 99% of games, object pooling is unlikely to make a visible performance difference.
Object pooling can also have a high cost as far as restructuring the lifetime of objects within your game.
I guess for a few bullets here and there I won’t be making my life harder. So it is not required for me. It’s not like I’m going to make the biggest bullet hell out there.
void Start()// Add 1 projectile in the pool at the start
{
GameObject projectile = Instantiate(projectilePrefab);
pooledProjectiles.Add(projectile);
projectile.SetActive(false);
}
This seems completely unnecessary. GetPooledProjectile already handles the case when there are no pooled projectiles available and creates one. I would guess this Start function is the source of your problem. Just delete it.
Well. When I was googling object pooling. I’ve seen people have some premade objects in the pool from the start. But at that time they had more of them premade so I’ve changed it. They had a for cycle there to add more of them. I’ve removed the for cycle and just added 1. Which is quite enough for weapons with slow fire rate. And I wanted to make it require the least memory as I could. It’s true that it’s quite useless now that I think about it. But the same issue arises when I’m adding another one into the pool. So simply removing this wouldn’t help.
Also I’ve already deleted everything related to object pooling and replaced that with the standard instantiate/ destroy method. I’m not going to rewrite the code anymore.