Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Instantiate time differing

Discussion in 'Scripting' started by dunloip, Aug 29, 2018.

  1. dunloip

    dunloip

    Joined:
    Aug 8, 2018
    Posts:
    15
    I have found a Unity behaviour that I don't quite understand: I was originally doing some performance testing, because a call to Instantiate() was taking what I considered too long (16ms), producing a drop on fps. This instantiation takes place on Scene2, and when I test the game playing from Scene2, the cost of this function is, as I said above, 16 ms.

    However, if I start testing the game from Scene1 (which is a very simple menu scene which has no relation with the instantiated object whatsoever), and Scene2 is then loaded from this menu, the same Instantiate() call, called from Scene2 as before, drops its cost and takes only 2 ms.

    I have tried it several times and I always get the same result. How can the loading of a previous scene affect its performance that way, when Scene2 is absolutely the same and the scripts in Scene1 have no relation with that Instantiate() call? I know it's a rather wide question to ask without any code, but I don't know which parts to paste. Any ideas why that might be happening anyway?
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,302
    What about a second time calling the same Instantiate the same way, is that always the same speed whether you start from menu or directly?

    If so I would say there‘s some resource loading happening which the menu scene already does, or perhaps allows unity to preload resources.

    It would be interesting how long the scripts associated with the instanced objects takr. Perhaps you have some heavy duty code for example FindObject in a complex scene hierarchy vs the instance already available because the menu scene already „found“ it.
     
  3. dunloip

    dunloip

    Joined:
    Aug 8, 2018
    Posts:
    15
    Thanks for the answer Steffen,

    A second call to the same method is much faster (less that 1 ms) both starting from Scene0 and Scene1, which led me to think that there was some cache mechanism to Instantiate.

    There is some GameObject.Find() in both scripts, but they look for different objects. And answering to your question, the instantiated script takes less that 1ms to initialize, which makes it even more weird. The instantiate call is here:

    Code (CSharp):
    1. public class Module : MonoBehaviour {
    2.  
    3.     private static Object buildingMenuPanelObject = null;
    4.     // ...
    5.  
    6.  
    7.     private void Awake() {
    8.         // ...
    9.         buildingMenuPanelObject = buildingMenuPanelObject ?? Resources.Load("Prefabs/BuildingMenuPanel");
    10.     }
    11.  
    12.  
    13.     private void OnMouseDown() {
    14.  
    15.         if (Input.GetMouseButtonDown(0)) {
    16.             if (!somethingBuilt) {
    17.                 // This assignation here is the problem.
    18.                 GameObject buildingMenu = Instantiate(buildingMenuPanelObject) as GameObject;
    19.                 // ...
    20.             }
    21.         }
    22.      
    23.  
    24.     }
    As I said, the script associated with the object instantiated takes <1ms to execute, so I don't know what is taking so long. May it be the GameObject casting?
     
  4. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,302
    Casting costs are negligible. I would look into the Resources.Load call. Try replacing it with some dummy object assigned in Inspector.

    In any case, is this a real problem users are going to face or will they always go through the menu? Does it appear in builds?

    If neither is the case the priority would be to move on, unless it somehow becomes unbearable while developing.
     
  5. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    Have you tried the profiler? That is probably the best place to start your investigations. :)
     
  6. dunloip

    dunloip

    Joined:
    Aug 8, 2018
    Posts:
    15
    It looks like is has to do with the performance of TextMeshPro:

    module1.png

    Now it makes sense why it took less time to Instantiate if it was coming from Scene0: the TextMeshPro's Awake was executed in that previous scene. However, I still have one doubt about the original problem:

    How would you recommend dealing with code that takes longer to execute than a frame? Is there a way in Unity to stop a method's execution and resume it the next frame? Coroutines come to mind, but I am not sure if they fit for this kind of operations.
     
    Last edited: Aug 29, 2018
  7. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    I understand what you are asking, but the question is kind of back to front. :) If I write some code that runs on the main thread and it takes, say, 5 seconds to run, then the game 'freezes' for 5 seconds. That is because that frame took (in excess of) 5 seconds.

    If you are targetting, say, 60FPS and there is a task to perform that takes more than 1/60th seconds to complete, then 3 options could be :-
    1. if no Unity API calls are involved (ECS aside), then you can run the task on a C# background thread.
    2. if Unity API calls are necessary and the task can be split into sections then a Coroutine would work.
    3. if Unity API calls are necessary and the task cannot be split (maybe parsing a huge JSON file, for example) then you might want to find a point in proceedings where the game freezing will not be noticed and take the hit there.
     
    dunloip likes this.