- Home /
Optimizing Projectile Creation and Destruction
I've been working on an action game for iOS in which a large number of projectiles and effects are being added and removed from the scene.
The projectiles tend to be sprites with a gameplay script, a spherical collision area and kinematic rigid body, and the effects tend to be sprites with just a game-specific script that determines their duration.
Early on, I just used Instantiate() to add bullets and explosions and such, but this preformed very poorly when many were added at once.
I later moved to the system of having a pool of each type of projectile that could be activated when 'fired' and de-activated when it would be destroyed. This resulted in a substantial improvement, however, on older iOS devices, the activation and de-activation of the gameObjects still caused a noticeable performance hit, especially in the case of bosses that shot large numbers of projectiles, or in the case where the player used a Contra-esque five shot spread weapon.
My final experiment was to not enable or disable anything, but simply to move the objects into the scene and then banish them when they were done. The problem here was that a massive spike in physics processing occurred whenever a projectile came on stage and began to move. Ultimately, this proved much less efficient than the second option.
The massive cache of banished projectiles were placed on layers such that they could not interact with one another but the presence of those active collision objects was heavily taxing to the distant objects when they moved, I suppose.
I feel like I must be overlooking a better fourth option for how to deal with this scenario. If there are any additional details that would aid the community in providing advice, I will be happy to provide them.
Answer by _Petroz · Jun 21, 2011 at 11:06 PM
You could try putting the rigid body to sleep when you teleport it in.
http://unity3d.com/support/documentation/Components/RigidbodySleeping.html
http://unity3d.com/support/documentation/ScriptReference/Rigidbody.Sleep.html
I tried adding some calls to put them to sleep, but I didn't see any change in performance. All of the rigid bodies on the projectiles exist only to do collision detection, so they're all flagged as kinematic.
They're only moved by moving their transforms with projectile-specific scripts. However, this movement still causes spikes in physics processing when I have hundreds of rigid bodies sleeping in the corner, as it were.
I don't need them active, and I don't get a physics hit if I de-activate the inactive projectiles. However, the enabling and disabling itself causes a different, but equally frustrating, performance drain.
I'm just wondering if you ever discovered a solution for this - it's difficult to tell what the issue may be without seeing your code. Do you have any inner loops in your script?
A clue is that you don't get a physics hit if you de-activate them. Is it because the projectiles on screen are still calcualting against the distant objects? A possible solution may be to turn off calculations in your script based on distance (anything that is off screen). Again, just a guess without seeing code.
Have you watched this Unity Optimization presentation? Great talk by Joachin Ante - it deals with optimizing a large flock of birds but might be relevant: http://video.unity3d.com/video/3272748/unite-07-performance
Answer by Muuskii · Aug 06, 2012 at 05:10 PM
Hi,
Since you brought up spread shots, that gave me an idea; Have you ever thought of making one object that controls the movement of all five projectiles? I assume you're using something like Object Pool where you can get an available GameObject returned whenever you need one this should be simple enough.
The reason why having one "master" object as opposed to five separate ones would help is because Unity has the overhead of finding each GameObject's Update function, calling it, it returns, find the next GameObject, etc, etc. Having one master object should theoretically reduce the overhead of calling Update functions by 80%? (I don't have Pro so I can't test this)
You could even go one step further and have your master object control ALL of the projectiles. Yes, this is pretty much taking a great system like Unity and ignoring most of it's features and reinventing it inside itself. (Unitiception?) But it might cut down a lot of overhead in the process, assuming you have hundreds of projectiles.
Have you also looked into Optimizing Graphics Performance and Optimizing Script Performance. That second link has an interesting part about disabling objects that are not relevant at the moment and caching your transform, if you're not doing that already.
Hope this helps!
Your answer
Follow this Question
Related Questions
Large level loading best practices 1 Answer
iOS. Jerks in first 15-20 seconds after starting scene 0 Answers
AC-130 Game help 1 Answer
iPhone game build size minimum 3 Answers