Jump to content
  • Advertisement
Sign in to follow this  
SpikeViper

Unity Should I leave Unity?

This topic is 881 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been making a game with Unity for quite some time. All code has been made with C# and I'm starting to get the game at a point where the basic elements work... but not smoothly. My problem is with Unity itself. The garbage collector is killing me because of the amount of objects my game has (I generate chunks, and in a planet there can be 20,000 chunks). I've been fighting the garbage collector for so long I'm wondering if I should look into another engine, or create my own. Would I be able to make an engine that uses C# as a scripting language and C++ as a main language, so I can manage my memory more efficiently? It seems that Unity isn't upgrading Mono for awhile, and until then, I'm not sure how I'm going to overcome this garbage (no pun intended). I have a lot of free time, and I'm young enough to learn C++ pretty easily, so I'm wondering if I should split off of Unity soon, before it's too late, and all my code becomes a trashy mess (once again, no pun intended).

 

Thanks!

Share this post


Link to post
Share on other sites
Advertisement

Seeing as you're talking about the garbage collector a lot, it seems like this is more of a problem of learning how to deal with large amounts of objects in a managed environment rather than a problem with Unity.

 

Object pooling will alleviate a lot of situations where you're dealing with lots of objects of the same type being created. In your case if you're dealing with chunks, it might be easier to pre-allocate a large batch of chunks off of which you can allocate and recycle chunks. In games I've shipped with Unity we had to apply this type of strategy a lot, for example for projectiles, effects and even pathfinding nodes if I remember correctly (I didn't write the pathfinding system).

 

Proper object management is not a problem that's unique to Unity, C# or even managed languages in general. In C++ you're going to have to reason about data flow and usage just as much if not even more, so rolling your own engine is not going to fix this problem.

 

Plenty of programmers like to blame garbage collection schemes for many of their problems, but there's often good solutions to avoid garbage collection issues which will eventually also benefit your code in terms of efficiency and cleanliness.

 

I'm already object-pooling the chunks. The problem is when I pass data to meshes, it seems to always create garbage.

Share this post


Link to post
Share on other sites

You'll have to provide some more details then.

What does "it seems to always create garbage" mean specifically? It's invoking the garbage collector? It's allocating a large amount of memory? Do you have any profiling data or other statistics to show what's happening?

 

Also, if you really suspect the garbage collector, are you sure your pooling strategy is correct and not doing any hidden redundant allocations? Is the step where you're passing along data to your meshes doing any redundant copies?

Share this post


Link to post
Share on other sites

The garbage collector is killing me because of the amount of objects my game has

Having a lot of objects should not a problem for a generational garbage collector anyway; deleting a lot of objects is a problem.
 
But a quick google search says that Unity doesn't use a generational garbage collector :(
I've shipped a lot of games using Lua, which also has a pretty terrible (non-generational) garbage collector, where the cost grows with the number of live objects. There's always ways to work around it :(
Firstly, avoid ever generating any data (deleting objects), as this creates work for even the best garbage collector. Reuse old objects when you can. e.g. if you know that a gun can fire a stream of 10 bullets, then you make a pool of 10 bullet structures and keep them around permanently (instead of a making a new one for each shot). Make objects bigger when you can -- 1 object of size 10 is better than 10 objects of size 1. In C# use structs over classes where possible, and flat arrays instead of more advanced collections. e.g. if you make an array of 20000 chunk structures, that would hopefully be a single 'object' as far as the GC is concerned.

Share this post


Link to post
Share on other sites

Just switching to C++ isn't going to fix your issues, you basically are saying I am going to write my own garbage collection and poof your issues are over. I think you will find you will be fighting a lot more with performance then you think you will. Language isn't going to do magic for you. City Skylines is made with Unity and I have seen massive cities built. Cars moving, we are talking 10's of thousands of objects at once. The pooling itself might not truly be the problem. Consider system requirements, what are you running maybe you have reached the maximum amount of performance you can get out of your rig. Look at some of the good pooling packages on the asset store. I'm not saying you are a bad programmer but I can't assume you are the best either so something has to give. You can crash a decent rig with a few objects and bad programming (No offense).

 

I  hope I didn't offend you just give a little advice on thinking of switching languages. Also if you want to learn C++ I am all for people learning multiple languages, I encourage this behavior. If you are serous can you look at UE4 you write your game in C++. You can always simulate your minimum game and see if you can get that to perform better for you.

Share this post


Link to post
Share on other sites

Just switching to C++ isn't going to fix your issues, you basically are saying I am going to write my own garbage collection and poof your issues are over. I think you will find you will be fighting a lot more with performance then you think you will. Language isn't going to do magic for you. City Skylines is made with Unity and I have seen massive cities built. Cars moving, we are talking 10's of thousands of objects at once. The pooling itself might not truly be the problem. Consider system requirements, what are you running maybe you have reached the maximum amount of performance you can get out of your rig. Look at some of the good pooling packages on the asset store. I'm not saying you are a bad programmer but I can't assume you are the best either so something has to give. You can crash a decent rig with a few objects and bad programming (No offense)

 

Unity actually has some problems specifically with generating large numbers of meshes, as for a chunked voxel world.  One issue is that you need to pass in arrays of the correct size as vertices, indices, etc., so you end up creating and destroying a lot of arrays and can't* do pooling for them.  Also, I'm not sure, but I think Unity creates its own copies of those arrays when you assign them to meshes.

 

Cities: Skylines isn't really a fair comparison; Unity's approach to procedural meshes and garbage collection might actually be a serious problem for a voxel-based world, as compared to other options OP might investigate.

 

I'm definitely not a Unity expert, so there might be solutions to these issues that I'm not aware of.  If there are, I'd definitely love to hear about them!  I do see voxel engines on Unity's Asset Store, so it's possible some people have figured it out, or at least gotten good enough performance.

 

*you CAN create and pool vertex arrays of size MAX_VERTICES and pass them in with the unused regions filled with junk.  I don't know if those junk vertices get transferred to the GPU, though.  Also, as far as I know that approach doesn't work for the indexing arrays.

Share this post


Link to post
Share on other sites

 

Just switching to C++ isn't going to fix your issues, you basically are saying I am going to write my own garbage collection and poof your issues are over. I think you will find you will be fighting a lot more with performance then you think you will. Language isn't going to do magic for you. City Skylines is made with Unity and I have seen massive cities built. Cars moving, we are talking 10's of thousands of objects at once. The pooling itself might not truly be the problem. Consider system requirements, what are you running maybe you have reached the maximum amount of performance you can get out of your rig. Look at some of the good pooling packages on the asset store. I'm not saying you are a bad programmer but I can't assume you are the best either so something has to give. You can crash a decent rig with a few objects and bad programming (No offense)

 

Unity actually has some problems specifically with generating large numbers of meshes, as for a chunked voxel world.  One issue is that you need to pass in arrays of the correct size as vertices, indices, etc., so you end up creating and destroying a lot of arrays and can't* do pooling for them.  Also, I'm not sure, but I think Unity creates its own copies of those arrays when you assign them to meshes.

 

Cities: Skylines isn't really a fair comparison; Unity's approach to procedural meshes and garbage collection might actually be a serious problem for a voxel-based world, as compared to other options OP might investigate.

 

I'm definitely not a Unity expert, so there might be solutions to these issues that I'm not aware of.  If there are, I'd definitely love to hear about them!  I do see voxel engines on Unity's Asset Store, so it's possible some people have figured it out, or at least gotten good enough performance.

 

*you CAN create and pool vertex arrays of size MAX_VERTICES and pass them in with the unused regions filled with junk.  I don't know if those junk vertices get transferred to the GPU, though.  Also, as far as I know that approach doesn't work for the indexing arrays.

 

 

My problem is on this line of code:

public void Rebuild() 
{ 
    vertices = new List<Vector3>(vertcount); 
    triangles = new List<int>(tricount); 
    uv = new List<Vector2>(uvcount); 
} 

In my MeshData class, I make lists to the EXACT size needed, by counting what I need beforehand. But, for some reason, on the FIRST time I allocate these lists (as above) it generates garbage. Why would it create garbage on the first time? I'm not replacing anything, just creating a new instance.

 

EDIT: Profiler specifically says "List1.ctor" I know this means constructor, but why is this making garbage???

Edited by SpikeViper

Share this post


Link to post
Share on other sites

Unity's profiler shows allocations, not garbage.


In my case I can see where GC.Collect is being called from, and I can see the memory used - both where I mentioned above.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!