I've made a simple 2D game in Unity using the application Tiled for the tilemap, but when I run it, every now and then the screen will jump like it has a quick fps drop.
I'm not sure what would be hurting the performance of the game, because it is not performing any demanding tasks. My only guess is that it could be the large tilemap I'm using, but I feel this is not the problem because the game was still jerky when the map was not large. Furthermore, I tried scaling the map to an even larger size but it didn't make the performance any worse than it already was.
Does anyone know what could be causing the performance issue here? Thanks.
Periodic frame-rate drops could be caused by a number of things - fortunately Unity gives you a very good tool to track this down in the form of the Profiler (Window > Profiler). It's recommended that you build the game (check Development Build and Autoconnect Profiler) rather than testing in the editor, as often the editor creates a lot of overhead that shows up in the Profiler and may lead you astray.
Play the game and see if there are any spikes when you notice the fps drop. I would not be surprised if you have Garbage Collection (GC) causing your periodic fps drops. GC is triggered periodically in the background to clean up memory that was allocated but is no longer needed. You can get a good idea of how much memory is being allocated by selecting CPU Usage and looking at the GC Alloc column. This can add up quickly! Optimising a game to avoid GC spikes is a whole topic unto itself.
But, of course, you problem might have nothing to do with GC spikes. Hopefully the Profiler will tell you which stones you should be turning over.
Related
I'm working on a game using C#/MonoGame and I'm wondering how to solve a garbage collection problem relating to large game objects in memory.
Every time I load a new game, I create and store a World object which itself has a private field containing a quadtree for my LOD terrain system. The quadtree recursively contains vertex information for all its possible child nodes, down to the smallest level I've decided I want. This means that each new World takes ~10 seconds to create (done on a background thread) and comes to ~150MB in RAM size.
I'd like to be assured that every time I load a new game, the old World is disposed, but as far as I can tell right now, this is never happening. I just tested it by pressing 'load game' six times in a row, and the memory used by my game was touching 1GB without ever dropping.
I know this could mean that I'm still referencing my old World objects, but I can't see how this is happening. My main game app has a single private World which is re-created from scratch as a new object on my background loader thread every time I press 'load game':
// This belongs to the game and is referenced when I want to interact with and draw the current World
private World _world;
.
.
// Executes on background loader thread when I press 'load game'
LoadGame()
{
// This is where the old World is replaced with the new one, so I want the old one to be disposed as it contains ~150MB of useless data
_world = new World(worldParameters);
}
.
.
Draw()
{
// Rendering the active World in our draw loop
DrawWorld(_world);
}
I tried setting _world to null and forcing the GC to collect at the top of the LoadGame() method, but that did nothing.
Is there a way I can force the memory for the old object to be freed, or even just see if I'm inadvertently pointing to any of its fields in the rest of my game, causing it to stay alive?
Memory allocation can be a tricky thing in garbage collected languages like C#. Ironically, these languages are designed so that you don't have to think too much about memory allocations. Unfortunately, for games having the garbage collector kick in during gameplay can be a frustrating experience for the player if keeping a consistent frame rate is important for your game.
There are two approaches that I'm aware of to deal with this kind of issue. The first is to explicitly call the garbage collector yourself.
GC.Collect();
GC.WaitForPendingFinalizers();
Keep in mind, this is a quick and dirty approach and it might not work the way you expect. Many people on the internet will tell you it's not recommended or a bad idea to force garbage collection. I'm no expert in the pros and cons, but I just wanted to make you aware that it's an option so you can do your own research.
The second approach is being smart about your data structures. Some circles might call this "implementing your own memory allocation strategy". Essentially what it boils down to is pre-allocating a big chunk of memory up front and reusing that space over and over again.
What the exact strategy looks like for you could be very simple, or very complex. My advice is to start with the simplest thing you can get away with and see how it goes. One of the patterns that might be helpful to look into is often called "object pooling".
We are working on simulation game. We have about 25000 objects at world. All has 1 unity c# script. If we activate empty update function we get 15 fps if we activate empty fixed update with 0.02 time scale we get 1-2 fps at average spec computer. In Will we need to do something on update function. So need some help for this performance problem.
In that case, what can we do for performance?
Thanks for advices and help.
Well even though your question is broad i will try to give some tips. My guess is you are doing some heavy calculations in your Update and this causes fps problems. Also rendering 25000 object at the same time would cause fps issues. First i suggest using Unity Profiler and Unity statistics to find out what is causing the issue. Then my suggestions would be based on the problem i assume:
Use Coroutines instead of doing all the calculations in Update.
Use Occlusion culling for rendering as minimum objects as possible. You do not need to render objects which are not in Camera frustum.
If you have meshes which are detailed use level of detail if you have the chance.
If you narrow down your problem i am happy to help further. Good luck!
The very need to make a call to Update() is one of the major slowdowns in Unity. That's why they are now pusing towards Entity Component System where there is no need for such jumps.
If all the objects are having the same script, it should be quite easy to modify the code so that only 1 object has the script, but operates (i.e. via a for (;;) loop) on all other objects. This should bring massive improvements already.
Aslo if theres any chance your objects share meshes - do use Instanced Mesh Rendering it is faster by two orders of magnitude
The first time I run my game and trigger an Animation, there is a pretty big CPU spike (last one was 153ms) which once investigated, led me to see that it was Unity loading the animations as needed and that was causing it, at least that's what I believe.
I have read around and everyone seems to say that having the assets in the Resources folder and using Resources.Load("") would fix it, however I am still running into the issue despite placing that in both Awake() and Start() methods on various objects. Am I doing something wrong? Or is there a specific way for me to load the sprites I need at load and would that stop the CPU spikes?
Ever since unity 4.5.x There is a way to use Resources.Load("") in a asynchronous way. This would allow you to prevent/reduce the spike in CPU usage quite a bit. The syntax for this being Resources.LoadAsync() In combination with a coroutine you should be able to resolve your issue.
If you need more detailed help with this, please include your actual code in your question as well.
I'm creating an XNA game and am getting an unexpected result, extremely low FPS (About 2-12 fps). What program should I use to test performance and track down what is slowing it down?
Have you tried using SlimTune?
You could also use StopWatch to measure sections manually.
Okay, let me bring my personal experience with game development in XNA.
The first thing you need to do is go into Debug -> Start Performance Analysis. This profiles your CPU activity and see's what threads are in use and what is doing the most processing.
You also need to factor in a couple of more things:
-You are probably running in debug mode, this means that some of your CPU is being dedicated to VS and to check for exceptions and what not.
-Your code might be inefficient. I recommend trying to limit the amount of Lists, Arrays, ADT's, and objects created during run time, because that slows it down a lot. Last time I checked the Game Loop ran 60 times a second so that imagine what a strain it would be to allocate a new List, then garbage collect it, 60 times a second. It starts adding up.
-I don't know how advanced you are, but read up on parallel threading, or multitasking.
An example would to have your physics engine 1 frames behind your graphics update.
EDIT: I realized you found your mistake but I hope this post can help others.
I'm a pretty big newbie when it comes to optimization. In the current game I'm working on I've managed to optimize a function and shave about 0.5% of its CPU load and that's about as 'awesome' as I've been.
My situation is as follows: I've developed a physics heavy game in MonoTouch using an XNA wrapper library called ExEn and try as I might I've found it very hard to get the game to reach a playable framerate on an iPhone4 (don't even want to think about iPhone3GS at this point).
The performance degradation is almost certainly in the physics calculations, if I turn physics off the framerate jumps up sharply, if I disable everything, rendering, input, audio and just leave physics on performance hovers around 15fps during physics intensive situations.
I used Instruments to profile the performance and this is what I got: http://i.imgur.com/FX25h.png The functions which drain the most performance are either from the physics engine (Farseer) or the ExEn XNA wrapper functions they call (notably Vector2.Max, Vector2.Min).
I looked into those functions and I know wherever it can Farseer is passing values by reference into those functions rather than by value so that's that covered (and it's literally the only way I can think of. The functions are very simple themselves basically amounting to such operations as
return new Vector2(Max(v1.x, v2.x), Max(v1.y, v2.y))
Basically I feel like I'm stuck and in my limited capacity and understanding of code optimizations I'm not sure what my options are or if I even have any options (maybe I should just curl into a fetal position and cry?). With LLVM turned on and built in release I'm getting maybe 15fps at best. I did manage to bring the game up to 30fps by lowering the physics precision but this makes many levels simply unplayable as bodies intersect one another and collapse in on themselves.
So my question is, is this a lost cause or is there anything I can do to beef up performance?
First of all, love your game on Windows Phone 7!
Secondly, I don't see anything out of the ordinary in your profiler output. I did a quick and dirty performance analysis of the Farseer engine once (running in .net) and came up with similar results. It almost looks like you have a slowdown that is proportional across the board and may be due to mono itself.
I suppose you follow the performance hints in http://farseerphysics.codeplex.com/documentation already :-)
The most important thing seems to be
to reduce complexity for the
collision detection calculations,
i.e. not the visual but the colliding
shapes. In Unijty3D they are called
colliders and you can attach a simple
cube as a collider to a complex human
body. I don't know anything about
Fareer but they probably have similar
concept (is it called body?).
If possible, try to replace your main
character or other complex objects by
easy cubes and check if fps raises.
Compiler switches sometimes leverage performance. Be really sure that there are no debug settings activated (I got up to 30 times slower code in a C++ library project). Ensure that armv7 optimisation is turned on and -O3 or -Os
Watch out for logging statements as they are extremely expensive on iPhone
[Update:]
Try to decrease the number of actively calculated AABBs just to find out which part of the physics engine causes the trouble. If it's the pure number follow FFox' advice.
What is about other platforms? Where did you perform the testing during the development phase, on simulator? Which one? Any chance to get it running on Android or Android simulator or Windows Phone? This would give you a hint if it is an iPhone specific problem.
Ah, I just saw that ExEn still is in pre-release state and the final will be launched on July 21th as OS. IMO this changes the situation: If your App is running fine on some other comparable platform, then just wait for the release and give it a new try. Chances are pretty well that there is still debugging code in the pre-release you are working on.