Search Unity

Speeding up Instantiate hitches

Discussion in 'Scripting' started by skyhawk, Sep 24, 2007.

  1. skyhawk

    skyhawk

    Joined:
    Jun 13, 2005
    Posts:
    49
    So I was playing with different things, and I noticed when I instantiated 50 spheres at once, I'd get a noticable hitch (around 450 ms). Is there things I can do to improve this?

    Is Instantiate overhead too high?
    Will reducing geometry fix this?
    Will lighting affect this too much?
     
  2. Willem

    Willem

    Joined:
    Mar 9, 2007
    Posts:
    184
    If you're spawning them all in the same frame, you're kind of boned. What I did in my game was to amortize the spawning of things over several frames.

    Say that I needed 10 new enemies spawned. I would spawn 2 each frame until I had 10 in total. The player really doesn't notice the difference between them all spawning at once or over the next 5 frames.

    So take your 450ms and say you broke it out to 2 per frame. You would then only be taking 18ms per frame to spawn enemies. Still not great but if you're doing that many you might want to go 1 per frame, which would only be a 9ms hit.
     
  3. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    Mesh colliders also add significantly to the instantiation time. If you can simplify or eliminate the colliders than that will speed things up.
     
  4. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,552
    And lighting will affect the framerate, if your using pixel lights. The fastest way to output this scene re: lighting is have no lights but increase the ambient lighting in the render settings

    So no bumpmaps for you Im afraid.
    AC
     
  5. forestjohnson

    forestjohnson

    Joined:
    Oct 1, 2005
    Posts:
    1,370
    Lighting doesn't effect instantiate speed.

    I think the best way to fix this is instantiate things one at a time, or remove mesh colliders and sounds. Or preload the sounds beforehand by assigning them to a source, and then doing audio.Play();audio.Stop();

    You might try instantiating one, then doing the other 49.

    In megapixel I got a hitch whenever I instantiated something for the first time.
     
  6. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,552
    Ok, I figured that if all 50 boxes are needing to be drawn more than once, that creates a load on the gpu, contributing to slooowdooown...

    But then that would apply everyframe. So without testing, I have my suspicions, but Yoggy's probably right in the end.

    I have in the past noticed a mini pause using instantiate, and definately the ctrl button being more reliable than fire 1, but always figured it was my code.
    AC
     
  7. thylaxene

    thylaxene

    Joined:
    Oct 10, 2005
    Posts:
    716
    yes that hitching is very noticeable if you are using mouse axis for movement at the same time. So much so that we had to shelf a game concept because of the jump in movement position with the mouse control everytime I instantiated several objects at once.

    But I'm glad it just wasn't my code as well :wink:

    So I might revisit the code with the above possible optimizations in mind.

    BTW what is the best way to delay instantiating over several frames? Is it just as easy as having a yield statement or two in your instantiating loop?

    Cheers.
     
  8. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    This isn't a side-effect of the first scene not being pre-loaded, is it? Have you tried starting with a blank scene that just opens the scene you want? That might speed things up in builds.
     
  9. skyhawk

    skyhawk

    Joined:
    Jun 13, 2005
    Posts:
    49
    no, this isn't first screen loading.

    This is "oh unit dies, now spawn 50 bullets that fire back at him"

    or "big bad mofo shoots 50 bullets in a giant arc at the player"

    I think this may all have to do with they are spawned relatively near one another, so there is a lot of "On Trigger Enter" happening.
     
  10. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    I get a hitch the first time I Instantiate stuff, but subsequent instantiates of the same prefab usually run smoothly. Is your problem a one-time thing, or does it happen each time you fire lots of objects?
     
  11. skyhawk

    skyhawk

    Joined:
    Jun 13, 2005
    Posts:
    49
    each time the best I can tell.
    I can post a demo up later.
     
  12. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    Are you using the built-in sphere object, or your own?
     
  13. skyhawk

    skyhawk

    Joined:
    Jun 13, 2005
    Posts:
    49
    built in.
     
  14. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    Well, that's not using a mesh collider so no help there. But it does have a lot more detail than you probably need for a small bullet. As an experiment, try replacing with cubes. If that helps but you don't like the look, then roll your own bullet mesh using a modeller.

    If the cube doesn't help, you may need to cache a set of bullets in an array. Create one new one every frame until your max is reached. Then grab one of those bullets when you need one, and let the cache manager slowly build the list back up for next time.
     
  15. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    I assume you mean instantiating them somewhere way outside the view (or world for that matter)? Which brings me to a couple of questions I've been thinking of asking for a while:

    1. As long as there aren't active scripts on objects outside of the view, I assume they don't add any overhead?

    2. When brought into the view, will they cause a hitch when loading textures, assuming the textures are loaded/unloaded as needed based on what's in the view (not sure if that's how it works)?
     
  16. Deleted User

    Deleted User

    Guest

    I have the same problem with Instantiate() in my maze web player and widget on http://www.fugugames.com/. It takes a few seconds to build the maze initially, and that's all taken up by the Instantiate calls to create the floor walls and ceiling for each cell of the maze (when you jump out the exit, the maze regeneration sans wall-building is effectively instantaneous).

    Each of maze surfaces is instantiated from the same prefab plane with bump-mapped texture. I started the maze out at something like 20x20 cells, but that took forever to start, so now I think it's around 12x12, so it's close to a 1000 Instantiate calls.
     
  17. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,552
    technicat, does that maze generate randomly? Im not sure why youd need to do that as oppposed to either instantiating 1 level, or just loading a level with one level mesh in it?

    dftdan
    "I assume you mean instantiating them somewhere way outside the view (or world for that matter)? Which brings me to a couple of questions I've been thinking of asking for a while:

    1. As long as there aren't active scripts on objects outside of the view, I assume they don't add any overhead? "

    My understanding is that if it had a collider, It needs to check for physics collisions, inside fixed update, so therefore is does have a cost. More so if it has a rigidbody too. Even if it had neither, I guess the engine still has to remember its there, though I imagine that cost would be really small.

    Im not the authority on this stuff but if I say the wrong thing someone will correct me
    AC :wink:
     
  18. skyhawk

    skyhawk

    Joined:
    Jun 13, 2005
    Posts:
    49
    just so people can see kind of what I'm talking about, this receives a small hitch (barely noticeable) when spawning 5.

    http://sky289hawk1.dyndns.org:8080/webplayer.html

    It's possible it might be the sphere mesh. Anyone have a simple Sphere model that's not too many polies? ^!^
     
  19. Bampf

    Bampf

    Joined:
    Oct 21, 2005
    Posts:
    369
    First I'd run a 5-minute test using the cube instead of the sphere. If that doesn't help then you'll be glad you haven't sunk much time into a dead end.
     
  20. Deleted User

    Deleted User

    Guest

    Targos,

    Yes, the maze generates randomly initially, and regenerates randomly each time you reach the maze exit.

    The maze walls could be prebuilt (all possible walls are instantiated once, and the random maze generation selectively deactivates walls, using a recursive algorithm that is described in the Wikipedia maze generation article), but the only reason not to generate them at runtime is to avoid the Instantiate delay. The nice thing about doing this at runtime is it keeps the web player footprint small (700k).
     
  21. Foxxis

    Foxxis

    Joined:
    Jun 27, 2006
    Posts:
    1,108
    I tested your maze demo, and it does take a while to set up. However, are you sure the delay is due to the instantiates? No offense intended whatsoever, but it seems a bit too long to be caused by only instantiates. Are you sure your maze generation code is efficient?
     
  22. Deleted User

    Deleted User

    Guest

    I'm sure the bottleneck is Instantiate - like I said before, the maze calculation runs every time you finish the maze, and that feels instantaneous. And the time is consistent with what skyhawk reported (he had 50 spheres over half a second, I have maybe 1000 planes over 3-5 seconds). But if that isn't consistent with the advertised performance of Instantiate (how long do you expect it to take?), I'll certainly dig deeper, or submit a bug report!
     
  23. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I dunno...I just did a simple test that instantiates 1000 spheres, and it takes .33 seconds if the spheres aren't visible, and .35 seconds if they are. With 50 spheres, it takes .047 seconds if the spheres aren't visible, and .049 seconds if they are. This is on a 2.5GHz G5.

    --Eric
     
  24. skyhawk

    skyhawk

    Joined:
    Jun 13, 2005
    Posts:
    49
    did those spheres have rigid bodies?
    The colliders are also triggers.

    Code (csharp):
    1.  
    2. protected virtual void firebackbullets(IcarusBaseObject emitter, IcarusBaseObject tar)
    3.     {
    4.         // don't fire back any bullets at player
    5.         if(GameManager.instance.isEasyDifficulty())
    6.         {
    7.             return;
    8.         }
    9.         // fire back at player if they are the same color as this AI
    10.         if(GameManager.instance.isNormalDifficulty())
    11.         {
    12.             if(isSameColor(tar.getColor()))
    13.                 firethebullets(emitter, tar);
    14.             return;
    15.         }
    16.         // fireback regardless of player's color
    17.         if(GameManager.instance.isHardDifficulty())
    18.         {
    19.             firethebullets(emitter, tar);
    20.             return;
    21.         }
    22.     }
    23.     protected void firethebullets(IcarusBaseObject emitter, IcarusBaseObject tar)
    24.     {
    25.         for(int x=0;x<backfirebullets;x++)
    26.         {
    27.             IcarusBaseObject bob = (IcarusBaseObject)Instantiate(GameManager.instance.Dot, transform.position + Random.insideUnitSphere * 5, Random.rotation);
    28.             Vector3 toTarget = (tar.transform.position + Random.insideUnitSphere * 10) - transform.position;
    29.             bob.setColor(emitter.getColor());
    30.             bob.rigidbody.velocity = toTarget.normalized * toTarget.magnitude / GameManager.instance.dotflytime;
    31.            
    32.         }
     
  25. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Nope, just colliders; adding a rigidbody approximately doubles the instantiate time. Naturally, the more stuff you have each object doing when instantiated, the longer it's going to take.

    --Eric
     
  26. skyhawk

    skyhawk

    Joined:
    Jun 13, 2005
    Posts:
    49
    I think it would more than double instantiating time. but I could be wrong.
     
  27. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Considering that I wrote a script which times it and I was getting about double the time, yep, I think you're wrong. ;)

    --Eric