Recycling rather than Instantiate / Destroy

I spent some time playing my arcade game on an iPhone 3G, and noticed occasional stutters in the game (about once every 6 or 7 levels) that are not apparent on the iPhone 4. Research says this may be due to garbage collection caused by the Instantiate and Destroy commands I use. The solution is to recycle rather than create and destroy.

Despite coming back to the subject regularly over the last week, I still do not understand the process. Whenever the subject is in enough depth, it also introduces other concepts as well. Having to understand which is relevant to my problem makes it doubly difficult. I was considering just leaving the stutters there, but I don’t want to do that.

Could someone please explain how I create an object so that it can be reused, how to activate that particular object when needed, and how to deactivate it?

To keep it simple. How would it work with a single enemy? (my enemies include child objects if that needs special consideration).

Funny. It was a problem in my project, for my final studies. It was on Virtools. Instantiating and deleting 3D Objects was CPU consuming, and it was clearly visible.

What I made was to make pools of game objects : array listing all gameobject, and whether they are “available” or not. Instead of instantiating, you request the next available game object. You iterate that array, and retrieve the first available game object. You set it to not available. Instead of destroying, you put it to sleep and make it available.

What makes a game object available ? Two possibilities : a boolean, for example…or one list filled with only available objects. When you are using one, you remove it from the list. When it become available again, you put it back.

1 Like

Thank you Akilaetribe. It is a bit easier for me in that I don’t need to test if a game object is available. I only create enemies at the start of a level when there are none. And I could create an array of bullets for the player, using the next one in turn with the array bigger than the number of bullets possible.

My problem is I don’t understand the process. For example I tried setting up a variable that created a prefab as a GameObject, then set active recursively to false so that it was not active now, but would be ready for when I did want it. For some reason this also turned off the GameObject that contained the script that created the new GameObject. also, if I commented out the set active false line, the GameObject acted several times as fast as a normal Instantiated version. As you can tell, I’ve got myself in a muddle and getting deeper.

What I’m hoping for is an explanation of what I need to do. Is it a GameObject I create rather than a Transform? How do I identify the object? etc.

p.s. I use Javascript, I can try and read .CS, but may struggle again

I believe this is what you’re looking for. It is what I’ve been using for pooled objects

http://forum.unity3d.com/viewtopic.php?t=36691&highlight=object+pool+manager

I’d seen that, but was worried that as it is .cs, I will have a black hole into which things go, but I could not sort out if things don’t work.

I did something like this for a pinball type game (Pachinko) where it recycled the same 20 or so balls. Basically, it required one prototype object and then went from there. As you requested them, it gave you one, then it would become inactive after some time and then your next request would give you the next one and so on. Sizing the pool wasn’t a huge problem, it was OK to be too big as having a few extra was a minor nuisance and too few would recycle them while still active.

UnityScript (JavaScript) and C# aren’t that alien from each other.

Unless you have some time pressures (is this just a personal pet-project of yours?) maybe you can take this as an opportunity to learn it.

In C#, there are strange things like ref or out, you don’t know how and when to use them…etc, etc, etc…senile mode

In Virtools, I had a script that managed from the beginning all pools. You define a number of objects per type, that won’t be reached (for example, my project was a shmup, there are tons of projectiles. So, the pool was filled with 200 objects). At the beginning of the game, the script (the pool manager, if you prefer) instantiate all objects.

For your information, when you instantiate a gameobject, all state are copied. So, if the prefab is disabled by default, copies are also be disabled.

If you are a programming veteran, you are even able to instantiate game objects and add them to the right pool if, during play, the reserve is not enough.

You need to find the right way to determine whether a game object is free or not.

For game objects with a limited lifespan, iterating over a built in array is the best solution (since you are iterating over and over an array, between the first and the second access to array [0], a good amount of seconds should have elapsed, and the game object should have been freed since).

For game objects with variable lifespan, two arrays are a solution. You iterate on a first array which only contains booleans (free ? not free ?). if true, you pick the game object of same index in the second list.

So, if Availability [×] == true, pick object [×], use it, and set Availability [×] == false;

Remember to store the index of each game object in his script, so you put the state back to true when it is time.

I’m putting the Object Pool Manager now. It took a while to get it to work, now it is going to take some more time to implement it.

It will be worth it if it does the job, although my first tests showed a big reduction in FPS. But I cannot judge properly until it is all in.

Eh, in my opinion, UnityScript handles those “strange” things like ref or out very strangely or not at all.

First off, UnityScript doesn’t even have the “ref” functionality, so if you want to emulate it you have to box the value in your own object manually. That said, it’s a pretty rare and special case to ever use that. The vast majority of the time, it’s not necessary.

As for “out”, I take issue with the UnityScript syntax of it because it has the exact same signature as a standard pass-by-reference object, but behaves differently.

That entirely different discussion asside, what you describe for the object pool is sound, and what was I was initially thinking to suggest (but didn’t want to take the time away from work to go into such detail) so props to you for taking the time.

The only other suggestion I can make, is that if you have a large number of objects, or performing many checks, looping through the array to find an available object may be innefficient. Or as you suggest, a bit cumbersome to add/remove objects from the pool. One possible solution would be to maintain one array of objects in use, and a stack of available objects. As you need an object, just pop it off the stack. And once an object is destroyed/freed, remove it from the array and push it onto the available stack. This way resizing the available object pool becomes a simple matter of removing/adding items from/to the available stack.

(if you’re feeling really fancy, you could use a HashTable/Dictionary for the active list so that the remove operation is always fast >.>)

? The idea of ref and out existing in UnityScript never crossed my mind, since I only saw them in C# scripts. Are we talking about the same language ? :slight_smile:

Wait, I never said you have to always begin the iteration from the beginning of the array ! Personally, I used an int which I increased whenever I parsed the array. When you reach the end, you put the int back to 0 (another way to make a for). That is for the first case, game objects with limited lifespan.

Of course, that’s a way to do it. Having an array only composed of available objects, removing them, and putting them back is maybe nicer (each has his pro and con, depending on factors and constraints).

They don’t exist in UnityScript – that’s the problem! :smile:

The array counter is a good idea; probably even faster than my suggestion as you never need to be resizing arrays. DAMN YOU

I read another paper on ref and out. Basically, those are a kind of pointer ? Instead of passing a value as an argument, you pass the variable, so when the argument is modified inside the function, the variable passed is also modified (allowing more flexibility) ?

It could lead to more interesting possibilities. Their lack is, indeed, regretful.

I always knew having to cope with Virtools insanities made me stronger…!

No one likes the chicken…He is too fat.
walks away, sadly

That’s pretty much it. Though “out” behaves a bit differently in that you pass a null object and the method will initialize it with a new instance. (or if you pass a non-null object, it will replace it with an entirely new instance)

The confusing part is that UnityScript actually does have “out” with methods like Physics.Raycast(). But the signature doesn’t indicate that at all, so unless you knew that’s what it did, you would not expect your original HIT variable reference to be overwritten with a new object.

I suppose, theoretically, C# could omit the “out” aspect of the syntax when invoking the method, but that would just make it confusing and inconsistent.

Also the chicken is awesome. Especially deep fried.

I implemented the Object Pool Manager for the enemies in my game and it halved the frame rate. So that is not an option.

Why do you lie …?

Moonjump, maybe there’s something up with your implementation or usage. Can you post your Object Pool Manager and give us info as to how many times you use it per frame?

Was that aimed at me? Because I am not lying. Maybe the Object Pool Manager was doing something incompatible with something else I am doing. It could be anything

I’m thinking of doing something simple. Player bullets are by far the most common Instantiation in my game, so I will look at creating a small pool of them. As I don’t understand the process normally used (which was why I was asking), I am considering creating my array of bullets. Turn off their renderer when not used, put an if statement in the Update loop so it nothing happens when inactive, reset the position and turn on the renderer when called.

Here it is:

http://forum.unity3d.com/viewtopic.php?t=36691&highlight=object+pool+manager

And I have no idea how many times is is called, as I don’t know what it is doing.

Looking at the code, it builds items as you request them and only reuses them once they are destroyed. So if you create 100 bullets before destroying any, it will create the bullet as you would normally using the Instantiate method. But if you destroyed/recycled any old bullets with the ObjectPoolManager, then it will be reused the next time you try to create a bullet.

So I guess the question is, are you using the pool to destroy your bullets as well?