I’m working on a simple FPS arcade style game for learning purposes, and I’m running into a huge performance issue when accessing the hit structure data after doing a raycast. To explain, this is for my health bars for the enemies. I have code working that causes them to only render in the OnGUI if they’re visible by the player, they work with health level, they position above the enemy, even scale correctly based on distance to the enemy. What I’m working on solving is obstruction culling with them. For example, if enemy #2 is behind enemy #1 such that the health bar for enemy #2 should not be rendered by the GUI. What I’m doing is a raycast from the player’s position to the enemy’s position. If the resulting hit.transform equals the enemy transform, I’m assuming visibility to the enemy and firing off the health bar render. The problem I have is in performance (FPS drops from average of 84 down to single digits). I’ve tracked down what’s dragging things down and it’s in this specific check:
if (hit.transform == transform)
{
}
Even with everything commented out inside the block, performance is still horrible. If I simply comment out the if statement, my FPS stays up where it should be. Can someone tell me why performing this check would completely tank performance? Or if I should be looking at a different approach to accomplish obstruction culling for the health bar rendering, I’m open for input as well. I’d like to know what’s going on, however, for knowledge of future techniques.
Ok, in case anyone else has this issue, I found what is the biggest problem. I had this check within the onGUI function itself, which for whatever reason tanks performance. I switched to using a boolean state for rendering the healthbar, moved all of these calculations and checks to the Update function, and my FPS stays fairly decent now. They don’t render correctly now, but that should be some simple calculation changes.
What might help a little is to keep a local variable with a reference to transform. But the main thing was that you moved the check to Update. OnGUI will be called several times pr. frame, which is why it was a bigger performance hit.
OnGUI is called at least once pr. frame and once pr. event happening during that frame, e.g. mouse move, key down etc. So that might add up.
You could maybe check it less often to get even more performance, maybe once pr. second or so in a coroutine.
Awesome extra info, thank you very much EdgeT. Now the issue makes sense. I didn’t realize the onGUI was called that often. Kudos!
~Scorp
Edit (added info): Although it is still curious that I only hit that bottle neck when accessing the hit.transform. Either way, resolved along with some good info to make it even better.
This is because hit.transform is not just a member accessor. It is a property accessor which I believe calls GetComponent under the covers. You really should cache its reference to a local variable if you’re going to repeatedly use it