Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Giant Spike Lag from Instantiate / GC.Alloc

Discussion in 'Editor & General Support' started by jasonoda, Aug 29, 2018.

  1. jasonoda

    jasonoda

    Joined:
    Sep 7, 2012
    Posts:
    67
    I'm having an issue with a character that shoots a fireball. The first time the fireball is shot by the character I get a giant spike and huge frame delay. In order to remedy this, I've instantiated a version of the fireball so it is cached in memory...but it still seems to happen. The spike seems like it has something to do with GC being called on instantiation of the fireball. Is there some reason why this is not working properly? What is the best practice for this sort of situation?

    Thank you.

    fireballSpike.png
     
  2. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
    You’re probably profiling in the editor, this isn’t always reliable to profile.
    But it seems like you’re running into the garbage collector(GC) taking a lot of time to collect. This is due to generating too much garbage in scripts.

    Try to profile it as a development build on the target platform.
     
  3. GloriaVictis

    GloriaVictis

    Joined:
    Sep 1, 2016
    Posts:
    133
    There is no Gc.collect on the frame you have shown - there's only allocation which is normal as you are instantiating object. You would need to check whats under Loading.ReadObject and takes so much time, also on the bottom of the screen you have PreLateUpdate.ScriptRunDelayedDynamicFrameRate which eats 18ms in total, you should check it too.

    Anyway, most probably you should also read about pooling objects.
     
    Hawke_Games likes this.
  4. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,091
    Ah you’re right, my bad.
     
    Hawke_Games likes this.
  5. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Best practice is using an object pool. In general, how this usually works is at the start of the game you instantiate a number of these fireball objects that you would reasonably expect to exist at the same time while playing the game. Say 50 for example. You instantiate them and set them inactive.

    Then when you would normally instantiate a fireball you instead request a fireball object from the pool. The pool provides the next available inactive fireball object and activates it as if it was just instantiated. When you're done with the fireball object you reset the object back to as if it was just instantiated and set it inactive, so that it is again available in the pool for later use.

    If you end up needing more fireball objects during gameplay than are available in the pool, you can have the pool instantiate an additional fireball object at that time. This should be relatively rare so won't impact the game as much as always instantiating every new fireball so is usually ok, but you could add a debugging message when this happens to tell you that you may want to increase the starting pool size to avoid this.
     
    radiantboy likes this.