Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
6
Question by RunSwimFly · Oct 04, 2012 at 06:25 PM · c#instantiateperformanceactivepool

Activating GameObject(s) is slow

I need to regularly bring groups of up to 500 GameObject(s) into the scene at run time as larger objects in my game world are broken and split into pieces. Instantiating them as needed was too slow. I then tried instantiating them upon start up, setting their active property to false and then setting it to true when they are needed. This was a little better. I then got a further improvement by leaving the dormant pieces active but instead turning off their colliders, renderers, scripts, setting them to kinematic and then sending them to sleep. Then when they are needed I reverse the process. Note though that these optimisations do impose a pre-calculation delay of several seconds at level start.

That's about as far as I can take it. The bulk of the slow down now appears to be occurring in Unity's internal processing and outside of my activation loop. And it's still a significant slow down. Breaking apart 4 objects into 100 pieces each still results in a worst frame time of around 200 milliseconds before it returns to a more healthy rate.

Until I get the full version of Unity and access to proper profiling tools I can't be much more specific than that. I will speculate though that Unity uses an adaptive voxel subdivision method for determining which objects to test for collision. This method may be optimised in some way to take advantage of spatial and temporal cohesion in the game world. Perhaps by suddenly activating a whole lot of new colliders in a single frame I'm disrupting this cohesion. If I don't activate the colliders the slow down is significantly smaller but pieces with no collision are useless to me.

So I'm currently clueless on how to get a couple of hundred objects into the scene without dropping frames. Has anyone had any success in doing this?

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
6

Answer by SinisterRainbow · Oct 14, 2013 at 09:42 PM

This is an old question but I had a similar problem and this is how I solved it:

First, I make liberal use of coroutines to hide loading/path searching/pooling/everything.. as a result, my game never appears to be loading, there's always something hiding it.

I faced a very similar problem to yours when working in CryEngine, whether they used R-trees or whatever for collision, I don't know, but adding the physics collider of the object caused the greatest lag.

There I needed to create a world with 15000+ objects as quickly as possible. I use pools for it, but masked under a 'coroutine' (equiv. in C++ anyway) that spawns the initial board around the player first, after a small set area I spawn the player and the game starts - The board still loads though and spirals it's way outward. So you may see a second of loading in front, but far off stuff is virtually unnoticeable. This doesn't bother me at all, but could possible be masked further through effects like dissipating fog or something of the like.

But that wasn't good enough even, so I disabled physics, spawned them and bam - incredibly fast.

SO - I came up with a new strategy: For the physics part I use a small radius around the player that physicalizes all objects around him/her. PLUS a slightly larger radius for any essential physics (like enemies, shootable stuff). Every x meters moved it will physicalize new objects in the direction the player moved within the radius, and unphysicalize those that have now left the radius. This is hidden in a coroutine as well.

This works well for even very fast movement. Though this full system is not applicable to your game I'm sure, realizing it's the physics likely causing the majority of the lag and figuring out a solution that may work for your case.

As a final note, this is easier to do in C++ perhaps: Is make sure your data is memory aligned. You can do basic things to assure this like nested for-loops, make sure it accesses data in the array in memory aligned order. It can be 100x faster to access memory aligned data than randomly or ( gasp )accessing it reversed order.

Comment
Add comment · 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
1

Answer by nikescar · Oct 05, 2012 at 10:44 PM

They way this is usually done is by using object pools. You instantiate the object from the start and keep them off screen until needed. Checkout this thread for an example. Also do a search here on Answers for "object pool".

Comment
Add comment · Show 1 · 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 RunSwimFly · Oct 06, 2012 at 04:46 AM 0
Share

Thanks nikescar. I'm familiar with object pools as a method of avoiding instantiation costs and use them elsewhere in my project. Indeed I started out using them for this problem but the individual pool objects I'm bringing into the world are joined together in arbitrary ways and creating joints on the fly isn't fast either. Also I can't cap how many might be present at any one time. So, rather than using a reusable pool I store a 1 to 1 copy of everything I'm going to need. It does the same thing, avoids instantiation on the fly. And, as listed above, I added the further optimisation of disabling and reenabling components rather than activating/deactivating as used in the pool example.

Over 80% of the time I'm now losing sits in bringing colliders (they are already created, just disabled) into the world which happens whether you use an active/inactive GameObject pool or the method I'm using. If I leave the colliders disabled (a 1 line code change) I get the 80% back. After further tests with "teleporting" colliders (leaving them enabled but making large positional changes) the slowdown also appears here. It looks to me that Unity physics just runs much slower on the first frame after a reasonable number of colliders appear in a new place. This is probably a function of the increased complexity of the problem and also it not being optimised due to the relative infrequency of occurrence. I've written physics engines before and this operation doesn't need to be as slow as this.

I do love my Unity though so I might just have to get creative at a higher level to avoid bringing too many objects into the world at once.

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

13 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

Related Questions

Distribute terrain in zones 3 Answers

Multiple Cars not working 1 Answer

Is there a way to optimize Loading.PersistentManager? 2 Answers

Object Pooling, have some question marks 0 Answers

Performance issues when creating many tiny objects 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