Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to know when a Instantiate has actually completed?

Discussion in 'Editor & General Support' started by 00christian00, Mar 14, 2015.

  1. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032
    In my game I am instantiating a large group of objects at runtime, and I have noticed that the Instantiate method is actually async, the method return almost immediately but the real object than take much more do appear.
    For example let's say I instantiate 1000 object, it finish in 1 sec but then it take like 4-5 second to appear.
    Is there a way to know when it has actually finished?
    It doesn't affect me in any way, because the game doesn't run until the instantiation has actually finished, but I am trying to optimize some parts and I can't know how long it does really take right now.


    I am using Unity 4.6.3, but it's the same with Unity 5.
     
  2. cannon

    cannon

    Joined:
    Jun 5, 2009
    Posts:
    751
    ?
    In my experience the main thread stalls until the instantiate completes.
    Is this with primitives?
     
    Nanako likes this.
  3. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    352
    I am sure that unless the instantiation of object is finished, the "parser" will not continue further.

    Example:

    Instantiate(someObject....);
    print("object spawned"); //This will not run unless the above code finished running, so the object is spawned

    So if your game will unfreeze after 1 sec, all the objects should be there. If you want better eprformance you can spawn objects in Coroutine so you will not have that big of an freeze spike.
     
  4. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032
    The main thread maybe,but not the current function.
    I am preloading everything manually and am trying to benchmark how long it takes to instantiate the prefab at runtime, to see which area of the game optimize to shorten loading times and if I need to optimized also my code( part of the level is procedural) but I don't know how to measure the actual time, because the instantiate method return soon but then unity do something after the instantiation.

    @Wrymnn
    Actually it does run! I tested it by generating 1000 prefab, and calculating the time difference between the start of the loop and the end, the loop complete in 1-2 seconds, but if the instantiated mesh is large it may take several seconds to appear.
     
  5. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Instantiate is completed immediately after the function is called, like every single other function, except those specifically labeled "Async". (Of which there are only a few.) It would be impossible to program if functions weren't 100% deterministic. All code is run on the main thread, unless you manually use System.Threading, however most of the Unity API can't be used in threads.

    --Eric
     
  6. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    Note, however, that it's possible that, technically speaking, the GPU may not execute the commands to RENDER the object until later, as its has its own queue separate from what the CPU is doing, if I understand it right. But probably in the big picture you never have to worry about that.
     
    Nanako likes this.
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    In any case the rendering would be done by the end of the current frame at the latest.

    --Eric
     
  8. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    352
    Yes.

    The computer always finishes to execute the task you have given it, so if you spawn those 1000 objects in one "pass" of main engine loop the objects will spawn and you will see them unless told otherwise in the background from other piece of code.
     
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Remember rendering only happens once a frame. So everything you Instantiate won't actually appear till te render step. Normally not a problem, unless you are doing some very heavy processing in the same frame.
     
  10. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    352
    Yes next frame, but never 4 secs after like OP states, that is maybe 200+ frames after....
     
  11. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Its entirely possible to write a frame that takes 4-5 seconds. Especially if its a loading frame. Best explanation I can come up with for the OPs symptoms.
     
  12. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032
    As I said before it's not an issue of seeing it, or lags. It's about measuring the time it take, in order to see which part of the level I can optimize to shorten loading times.
    There is no problem at all, just I don't know how to measure the time since something happen outside the update or start method and I would like to know if there is any way to measure the time spent in that part, that's all.
     
  13. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Time.realtimeSinceStartup?

    --Eric
     
  14. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Just run it though the profiler. Use Profiler.BeginSample and Profiler.EndSample to wrap the area of concern.
     
    glenneroo and drawcode like this.
  15. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032
    Time.realtimeSinceStartup is what I am using, but right now I am calculating the delta inside the start method, maybe I can try calculating it between the loading frame and the next one, so that it will account for the gpu part too hopefully.

    Didn't know about Profiler.BeginSample,look handy. Cool, gotta try it.
     
  16. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    352
    I said 200 frames after not 1 frame that takes 4 sec.
     
  17. cannon

    cannon

    Joined:
    Jun 5, 2009
    Posts:
    751
    @op, you might want to use frameCount to see if the game is truly running ahead of the instantiations.
     
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Why? That's not what happens; Instantiate always takes one frame.

    --Eric
     
    Kiwasi likes this.
  19. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Who cares what you said. It doesn't match up with what the OP said. Instantiate takes one frame. So if its taking four seconds for instantiate to complete, that means that one frame is taking four seconds. Totally plausible if you are creating 1000+ objects.
     
  20. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    I don't know if this is also an issue with the call completion vs the mesh being rendered, but if you wanna know when something is completed, maybe your object could have a script on it that removes itself on Start but also tells some static variable somewhere that it's ready to use?
     
  21. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    352
    " it finish in 1 sec but then it take like 4-5 second to appear."

    If you can`t read don`t use this forums. By OP object will "appear" after 4-5 sec, this is not 4-5 sec freeze time but normal time when frames are running. So it is roughly 200 frames.
     
    Last edited: Mar 16, 2015
  22. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    Can you show your test code?

    My guess is that the loop which calls instantiate takes 1 or 2 seconds, but that other stuff going on (like maybe when the instantiation actually happens?) takes an additional two or three seconds. I would expect that to be a single frame that takes ~5 seconds, though, not the multiple frames as people are discussing.

    Alternatively, is anything being done in a coroutine?
     
  23. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Awake() is called in the newly instantiated object immediately after it finishes resolving.
     
    00christian00 likes this.
  24. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032
    My code is a simple
    Code (CSharp):
    1. _time = Time.realtimeSinceStartup;
    2. Do instantiation loop
    3. print("elapsed time 1 " + (Time.realtimeSinceStartup - _time));
    I think I found the issue. When I noticed the difference I was using probuilder object to test and they must do something at either "Start" or "Awake" so of course these weren't taken into consideration in my benchmark because they still hadn't run.

    Now I am calculating the time like this:
    Code (CSharp):
    1.  
    2. void Update () {
    3.  
    4.         if(benchmark)print("elapsed time 2 " + (Time.realtimeSinceStartup - _time));
    5.         benchmark=false;
    6.  
    7.     }
    8.  
    This way I can account for any loading script I throw in the instantiated prefab.
     
  25. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    Do you think Start would be much longer?

    Maybe this can be solved by checking if the object is being rendered. I know there's a way because I remember in 1 project I had to tell an object to animate at all times because by default if I looked away from it, it stopped animating. I knew because of some code I had executing at certain frames of the animation.

    Maybe renderer.isVisible would do it.
     
  26. 3agle

    3agle

    Joined:
    Jul 9, 2012
    Posts:
    508
    Perhaps OnWillRenderObject() will do it?

    That animation issue you mention seems related to the AnimationCullingType?
    I know that has been the case for me at one point. (I've ended up not changing the culling modes as it cause more problems than it fixes from a bug-hunting perspective :p )
     
  27. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    That's not what happens in reality, though, as people have been explaining. If you can't read, don't use these forums.

    --Eric
     
  28. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    Something like that probably.

    I had some metal clanking noises tied to animations of the lower half of robot kyle's body for when ever his feet struck the ground. That's the only reason I messed with default animation stuff. I couldn't figure out why the sound stopped every time I looked away. Then in code I added some of those render checks and animation play checks and saw it all stopped when ever he was out of view. I'm sure there's better ways to go about it, but I was trying to rip off of FNAF so performance and efficiency were not concerns, as there wouldn't be much going on at any point besides the robot.

    Mod-slapped! Hmm... Eric-slapped! Hmm... I dunno which is better.
     
  29. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,032
    Read above guys, I solved it. I wasn't accounting for the script in the prefabs which aren't loaded immediately on the Instantiate function.
     
  30. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    start is called at the beginning of the next frame after it's created, i believe. That could be a millisecond away, or an hour (if your game crashes)