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 /
avatar image
0
Question by ALLCAPS · Oct 18, 2013 at 01:26 PM · c#gameobjectperformancegeneration

Generate many (32k) GameObjects approach

Here is the project in question. There are a bunch of scripts, but the one we're concerned with is "GenerateMap.cs", it's in the Assets/Scripts folder.

https://github.com/mikezila/uQuake1

This project loads unmodified Quake 1 maps, and recreates them in Unity, just like it says on the tin. Parsing the maps themselves into C# objects is very fast. Even massive (by Quake 1 standards) maps are fully parsed into ready to use C# objects in less than a second. The issue is when it's time to make GameObjects for them.

Currently I'm making every surface in the map (called faces in .bsp lingo) into its own GameObject. On small deathmatch maps this results in about 3k objects, startup time of around a second, and 100fps. Great. On the massive maps, I end up with 32k GameObjects. It takes around 20 seconds to start, though performance isn't too bad once it's loaded, considering.

I'm not so concerned about the performance once the game is running, as I can implement the "vis" data from the .bsp and turn off the renderer on gameobjects that aren't visible, but how can I speed up the generation of the GameObjects? Or is there a better way?

Each object has the following:

  • A mesh filter and renderer

  • A mesh collider

  • A texture that is generated at runtime from the .bsp itself

In case you can't be bothered to look at the code, the basic process I'm using is this. Foreach face, create a gameobject, calculate the verts and tris for the mesh, calculate the uvs for the mesh, add components I need, add the verts, tris, and uvs to the mesh, recalculate normals, mark the object as static, done and onto the next face.

It's very simple, but with so many objects, it's slow to start up on the big maps. I don't have Unity Pro, so I can't use the profiler. Is there a valgrind/cachegrind type inspection I can perform somehow? Anyone have any tips on how I can speed this process up?

Comment
Add comment · Show 9
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 Khada · Oct 18, 2013 at 01:48 PM 0
Share

Can you serialize the data to avoid the conversion process?

avatar image ArkaneX · Oct 18, 2013 at 01:49 PM 0
Share

A quick thought - is it really necessary to convert each face to a game object?

avatar image ALLCAPS · Oct 18, 2013 at 02:05 PM 0
Share

@$$anonymous$$hada The conversion (I assume you mean parsing the .bsp itself) is fast enough. I do need to do dotproducts to figure out my texture coords, but otherwise there aren't any major calculations left to be done once the .bsp is parsed. it's all just grabbing things (like Vector3s and Texture2Ds) from arrays. If you mean something else I'm not following.

@ArkaneX That's why I'm here. I don't need each face as it's own object. I'd like to find out if it's slow to startup because of the number of GameObjects, or because of the work to make them. Really the only thing I could do to consolidate objects is to make one object per leaf (think section) of the .bsp and have all the faces be submeshes. Not sure how I'd to texturing in that case, since textures are defined per-face. This would be the same amount of work, though. I'd still need to make one mesh per face because of how they're stored in the .bsp.

avatar image ArkaneX · Oct 18, 2013 at 02:21 PM 0
Share

I don't know if going submeshes way will help, but if you want to check how long a specific portions of your code take, you can use System.Diagnostics.Stopwatch class.

I suggest to divide your code to more than one foreach (creating empty game objects, creating verts and tris, recalculating normals, etc.) and measure completion time of these steps.

After you see that one particular step takes a lot more, you can think on optimizing it. For example, if creating empty objects takes 50% of time, maybe it's a good idea to create a pool of these objects before user selects a map, and then just take prepared objects and continue with next steps.

avatar image ALLCAPS · Oct 19, 2013 at 08:43 PM 1
Share

Using that video and some elbow grease I converted all of my Lists to static length arrays, now when I do a release build the startup has gone from 2 and a half $$anonymous$$utes, to 2 and a half seconds. Video is great.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Loius · Oct 18, 2013 at 04:44 PM

Some of the slowest things you can do in unity are creating gameobjects and creating meshes. The more stuff you can do before creating an object or assigning a mesh to it, the better.

I'm not convinced that you have to have every face as its own gameobject. Objects can have multiple materials - I think that's controlled by submeshes. Pretty sure. Haven't really touched them apart from directly copying them, though.

What I'd do is keep a dictionary of < Texture, Mesh > for face-textures to sub-meshes:

 if ( dictionary.ContainsKey(currentFaceTexture) ) {
     targetSubmesh = dictionary[currentFaceTexture];
 } else {
     targetSubmesh = new Mesh();
     dictionary.Add(currentFaceTexture, targetSubmesh);
 }
 targetSubmesh.AddVerticesAndUVsAndStuff(faceInfo); // this function probably doesn't exist

You'll probably do well to generate chunks rather than a single massive object (one chunk per leaf is probably a good size). So build all your submeshes (remembering that the vertices have to be offset by the face's position now, since they're not each their own gameobject), then assign them to your main mesh, then assign that mesh to the chunk's game object.

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 ALLCAPS · Oct 18, 2013 at 09:37 PM 0
Share

I did some testing with .Stopwatch, and the results are very odd. All results are in milliseconds. "Stalwart" is a smaller map, "Ivory" is a huge map. Stalwart results in ~1.3k objects, Ivory results in ~32k objects.

 BSP Parsing (Includes generating Texture2Ds)
 Stalwart = 21
 Ivory = 249
 
 Create dummy gameObjects (Totally empty)
 Stalwart = 113
 Ivory = 137707, 132010, 139036
 
 Create actual gameObjects (Fully recreate the map)
 Stalwart = 303
 Ivory = 68481, 70708, 72564

Why is it more expensive to generate empty gameobjects than it is to generate the same number of objects while also doing all the work needed to fill them with a mesh, uvs, and etc.?

avatar image Loius · Oct 21, 2013 at 02:49 PM 0
Share

With numbers that huge, Unity sometimes gets into unstable territory. There's probably some weird memory stuff going on; I'm no expert. $$anonymous$$y best guess would be that the other stuff you're doing takes 'so long' to do that the weird memory stuff can settle down in between creating objects.

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

17 People are following this question.

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

Related Questions

Most optimal way of changing all textures on scene 1 Answer

How to get the GameObject reference with using trees in script? 0 Answers

MonoBehavior.Start() called infinite times? 1 Answer

Mesh.CombineMeshes does not work when mergeSubMeshes=false 2 Answers

Distribute terrain in zones 3 Answers


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