Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This post has been wikified, any user with enough reputation can edit it.
avatar image
2
Question by TheEnigmist · Jun 15, 2012 at 11:39 AM · terrainterraindatamemory leak

TerrainData uses too much memory

I'm generating in-game terrain with a script. Each terrain as a size of 2000 width, 100 or 300 height, 2000 lenght and each terrain as a heighmap of 128. If i create 100 terrain Unity uses 1,6GB of memory when i expected to use max 50MB for all terrain... I made a search and i found that is a TerrainData problem that uses a lot of memory... How can i fix this problem? This is my generator script. To run it in real-time i put it inside an empty game object.

 public class WorldGenerator : MonoBehaviour {
     
     private int worldSize;
     private const int tileSize=2000;
     private GameObject tGameObject;
     
     // Use this for initialization
     void Start () {
         worldSize=10;
         for (int i=0; i<worldSize; ++i)
             for(int j=0; j<worldSize; ++j){
             TerrainData tData = new TerrainData();
             tData.SetDetailResolution(2048,8);
             tData.baseMapResolution=1024;
             tData.heightmapResolution=128;
             tData.size=new Vector3(tileSize,600,tileSize);
             tGameObject = Terrain.CreateTerrainGameObject(tData);
             tGameObject.name="Tile "+((i*worldSize)+j);
             tGameObject.transform.position=(new Vector3((float)tData.size.x*j,(float)0,(float)tData.size.z*i));
         }
         Debug.Log("World generated in: "+Time.realtimeSinceStartup);
     }
 }

The memory used by Unity is like this:

  • Startup Unity -> 130 MB

  • Start Generator -> 1,7 GB

  • Stop Generator -> 400 MB

  • Start again Generator -> 1,7 GB

  • Stop it -> 750MB

Why i get this error?

If i restart unity it uses again 130MB. If i put Destroy(tData) at the end of for it uses 538MB but no terrain is displaied! If i use DestroyImmediate(tData) it uses 151MB but get a MissingReferenceException!

How can i generate terrains without using all that memory?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
4

Answer by jc_lvngstn · Jun 15, 2012 at 04:38 PM

I actually use a separate unity project to create my terrains. I then store all terrain data to files. One file for the height data, one for the tree data, one for the details, etc etc.

In my player, I just have four terrains in the game world, each one 128x128. My scale is different than yours, but that's fine. As the player moves, I find out if the player has moved far enough to bring more terrains into view. I don't delete the "far" terrains and recreate the new "close" ones the player is moving into. So let's say you have something like this:

 1  2  
 3  4

And the player is inside those 4 terrains, and moves east. The regions they are moving into are A and B

 1  2  A 
 3  4  B

I just load the terrain for A and B DATA into 1 and 3, and move 1 and 3 over to their new positions (where A and B would be placed). I don't recreate the new terrain game objects and destroy the old ones. That seems to gobble up memory badly.

So, when your player starts, you can load all the world terrain data from the files in advance, or you can just load the ones you need in the background. Maybe do some caching.

So...your gameworld can be huge, you are only dynamically loading the terrain data for those 4 terrains, as the player moves around.

That's it in a nutshell, at least how I am doing it. You basically have to serialize and deserialize the terrain data. I just used the BinaryWriter and BinaryReader to do this in C#. Works great.

I guess if you are actually storing the terrain in your project, then may be able to pull that data from the assets. I haven't done that, it really wouldn't suite my needs for my project.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image TheEnigmist · Jun 15, 2012 at 05:08 PM 0
Share

Good, this is what i thought :D I will try to do the same with my project... i don't create terrain in other project 'cause i want to generate different worlds at runtime. So all obaject are set in one project

avatar image XaVause · Oct 29, 2012 at 12:44 PM 0
Share

Hello, I'm trying to save terrainData, but it doesn't work. What are you doing exactly ? Can you share you code for this part ?

Thanks...

avatar image
2

Answer by Wolfram · Jun 15, 2012 at 11:54 AM

Well, with tData.SetDetailResolution(2048,8); you are specifying a detail resolution of 2048x2048 per terrain. That's your 2048x2048x100x4=1.68GB right there. You'll have to reduce that.

Also note that one "splat map" (the data structure storing your painted details, which is essentially a RGBA texture (hence the "x4")) can hold only 4 different detail types (painted textures, tree details, grass details) I think, so if you are using for example one basemap, 3 additional painted maps, two grass types and one rock type, you would already need (3+2+1)=6 detail types, so you would need two 2048x2048 detail maps for that terrain.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image TheEnigmist · Jun 15, 2012 at 01:23 PM 0
Share

I see, i changed SetDetailResolution in tData.SetDetailResolution(1024,8). Unity uses 1,3GB of memory when 400$$anonymous$$B was expected! (1024x1024x100x4=400$$anonymous$$B)

What is wrong?

There still a problem, when i stop the test unity doesn't clean all memory... why?

avatar image Wolfram · Jun 15, 2012 at 03:11 PM 0
Share

Please don't post comments as answers.

To answer your question, it's a combination of base map resolution, detail map resolution, and height map resolution. All three need to be stored, and all three contribute to the total size. I might be wrong about the distribution I explained in my answer (e.g., maybe the painted maps belong to the base maps), and there might be additional datastructures required for the detail objects (orientation, size per object, ...), so it might use more than 4 bytes per "pixel" for the detail map. Also, the second parameter "resolutionPerPatch" also influences the memory amount required (the smaller, the higher).

1024 basemap (=400$$anonymous$$iB=420$$anonymous$$B) plus 1024 detailmap (assu$$anonymous$$g 4 bytes per "pixel") plus 128 heightmap@16bit plus Unity Editor plus other overheads bring you much closer to the 1.3GB you are seeing.

Suffice it to say, the only way to reduce the amount of memory required is to reduce the individual resolutions. You might want to consider storing the tiles as Assets only, and just loading the full resolution tiles on demand, and otherwise using a low resolution map for tiles further away, etc.

When the Player stops, the memory is marked as available, and the GarbageCollection might actually free some of it immediately. But not necessarily all of it, mostly due to memory fragmentation. This doesn't mean there is a memory leak - that's why if you hit "Play" again, the size doesn't increase further than your previous max value.

avatar image TheEnigmist · Jun 15, 2012 at 04:01 PM 0
Share

I see... so a good way to play with terrains is to load max 3/4 of them and load only terrains near the player! How can i store item as Assets and load them dynamically and how have i to modify my script to reach this? Before reading i was thinking about to store in a file all the info of all terrains and create one when player is near and delete one when is far or not inside player's view!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

7 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Create Terrain withTerrainData 0 Answers

**Trying to access out-of-bounds terrain height information** When calling TerrainData.GetHeights(); 0 Answers

copy smaller size terrain's data, and seet the heights on bigger Terrain at click position 0 Answers

Unity imports heightmaps in kind of upside down order. 0 Answers

Default TreeInstance.color 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges