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

Huge overhead spike after generating a gameobject in Unity 5.3 iOS

Discussion in 'Editor & General Support' started by Neonlyte, Jan 23, 2016.

  1. Neonlyte

    Neonlyte

    Joined:
    Oct 17, 2013
    Posts:
    513
    Dear Unity Community,

    So recently I tried upgrading my iOS project from 5.2.3 to 5.3.1. I did not change my code or anything I just directly recompiled the project and the project started to have a CPU time under this section rather than staying zero. In some scenes this CPU time increased drastically and my frame rate dropped to 50fps while in 5.2.3 the same scene would stay at 60fps.

    Frame rate is essential for my project. I would like to know if anyone else is also having the same issue.

    In my scenes there are dozens of particle systems. Frame rate would drop when my code generate new gameobjects in the scene.

    I tried to narrow down the issue so I used profiler. I do see spikes when new gameobjects are generated. Sometimes they are caused by overhead, and sometimes by my generator code. I need to optimize my code for sure since the spikes caused by my code also appeared in 5.2.3.
    However, the overhead spikes comes immediately after my generator spikes as shown in the screenshot...

    I do not know what overhead means and what it relates to. Anyone got an explanation?

    QQ20160123-0@2x.png
     
    Last edited: Jan 23, 2016
    Nith666 likes this.
  2. Neonlyte

    Neonlyte

    Joined:
    Oct 17, 2013
    Posts:
    513
    Update:
    This is the result I get running my project on iPad Air with Unity 5.3.1p4. This huge Overhead spike caused the graphics hiccup. This spike will occur in a duration of seconds.

    QQ20160124-0@2x.png
     
    Nith666 likes this.
  3. Neonlyte

    Neonlyte

    Joined:
    Oct 17, 2013
    Posts:
    513
    Anyone who also have this issue...?
     
    Nith666 likes this.
  4. Neonlyte

    Neonlyte

    Joined:
    Oct 17, 2013
    Posts:
    513
    The spikes also come from frames after generating a GameObject. The spike that comes before the overhead spike is caused by MeasureClock.Update(). The update function is used to procedurally generate GameObjects.

    Any interpretations on why the overhead occurs would be really appreciated. :)

    QQ20160129-0@2x.png

    The function that gets called in MeasureClock.Update():

    public void spawnNote(NoteObj theNote, GameObject IndicatorRef, bool isSimulatious = false)
    {
    GameObject NoteTouchArea = new GameObject();

    NoteTouchArea.transform.parent = CanvasNoteGroupRef.transform;
    RectTransform NoteRectTrans = NoteTouchArea.AddComponent<RectTransform>();
    NoteRectTrans.anchoredPosition = new Vector2(theNote.notePositionX * 2, theNote.notePositionY * 2);
    NoteRectTrans.sizeDelta = new Vector2(350, 350);
    NoteRectTrans.localScale = new Vector3(1, 1, 1);

    Image NoteTouchAreaImage = NoteTouchArea.AddComponent<Image> ();
    NoteTouchAreaImage.color = new Color (1, 1, 1, 0);

    GameObject NoteMesh = new GameObject();

    MeshFilter NoteMeshFilter = NoteMesh.AddComponent<MeshFilter>();
    NoteMeshFilter.mesh = NoteMeshModel;

    MeshRenderer NoteMeshRenderer = NoteMesh.AddComponent<MeshRenderer>();
    NoteMeshRenderer.material = NoteSkinRef;

    NoteMesh.transform.parent = NoteGroup.transform;
    NoteMesh.transform.localScale = new Vector3(125,125,0);
    NoteMesh.transform.localPosition = new Vector3 (theNote.notePositionX, theNote.notePositionY, 2500);

    if(isSimulatious)
    {
    NoteMeshRenderer.material.color = new Color (1,1,199f/255f,0);
    FadeOnDistance NoteMeshFadeFX = NoteMesh.AddComponent<FadeOnDistance>();
    NoteMeshFadeFX.RTSettings = this.RTSettings;
    NoteMeshFadeFX.PresetNoteColorB = 199f/255f;
    }
    else
    {
    NoteMeshRenderer.material.color = new Color (1,1,1,0);
    FadeOnDistance NoteMeshFadeFX = NoteMesh.AddComponent<FadeOnDistance>();
    NoteMeshFadeFX.RTSettings = this.RTSettings;
    }

    if(theNote.isHold)
    {
    GameObject HoldMesh = new GameObject();

    MeshFilter HoldMeshFilter = HoldMesh.AddComponent<MeshFilter>();
    HoldMeshFilter.mesh = NoteMeshModel;

    MeshRenderer HoldMeshRenderer = HoldMesh.AddComponent<MeshRenderer>();
    HoldMeshRenderer.material = HoldSkinRef;
    HoldMeshRenderer.material.color = new Color (1,1,199f/255,0);

    HoldMesh.transform.parent = NoteMesh.transform;
    HoldMesh.transform.localScale = new Vector3(1.6f,1.6f,1);
    HoldMesh.transform.localPosition = Vector3.zero;

    FadeOnDistance FlickMeshFadeFX = HoldMesh.AddComponent<FadeOnDistance>();
    FlickMeshFadeFX.RTSettings = this.RTSettings;
    FlickMeshFadeFX.PresetNoteColorB = 199f/255f;
    }
    else if(theNote.isFlick)
    {
    GameObject FlickMesh = new GameObject();

    MeshFilter FlickMeshFilter = FlickMesh.AddComponent<MeshFilter>();
    FlickMeshFilter.mesh = NoteMeshModel;

    MeshRenderer FlickMeshRenderer = FlickMesh.AddComponent<MeshRenderer>();
    FlickMeshRenderer.material = FlickSkinRef;
    FlickMeshRenderer.material.color = new Color (1,1,199f/255,0);

    FlickMesh.transform.parent = NoteMesh.transform;
    FlickMesh.transform.localScale = new Vector3(1.6f,1.6f,1);
    FlickMesh.transform.localPosition = Vector3.zero;
    FlickMesh.transform.localEulerAngles = new Vector3(0, 0, RecastAngle(theNote.FlickAngle));

    FadeOnDistance FlickMeshFadeFX = FlickMesh.AddComponent<FadeOnDistance>();
    FlickMeshFadeFX.RTSettings = this.RTSettings;
    FlickMeshFadeFX.PresetNoteColorB = 199f/255f;
    }

    BasicMovementMod NoteMeshMovement = NoteMesh.AddComponent<BasicMovementMod>();
    NoteMeshMovement.PosX = theNote.notePositionX;
    NoteMeshMovement.PosY = theNote.notePositionY;
    NoteMeshMovement.HitMeasure = theNote.posMeasureCount + theNote.posMeasureOffsetFree;
    NoteMeshMovement.RTSettings = this.RTSettings;
    NoteMeshMovement.GameRTClock = this.ClockRef;

    NoteBinding BindingInstance;

    if (theNote.isHold)
    BindingInstance = NoteTouchArea.AddComponent<HoldNoteBinding>();
    else if (theNote.isFlick)
    BindingInstance = NoteTouchArea.AddComponent<FlickNoteBinding>();
    else
    BindingInstance = NoteTouchArea.AddComponent<NoteBinding>();

    BindingInstance.ClockRef = this.ClockRef;
    BindingInstance.theNoteObj = theNote;
    BindingInstance.JudgementActiveEntry = RTSettings.EntryJudgement;
    BindingInstance.JudgementActiveExit = RTSettings.ExitJudgement;

    BindingInstance.NoteMeshEntity = NoteMesh;
    BindingInstance.transform.SetAsFirstSibling();

    BindingInstance.ExplosionLoadRef = this.ExplosionLoadRef;
    if (theNote.isHold) {
    ((HoldNoteBinding)BindingInstance).HoldSpriteLoadRef = HoldExplosionLoadRef;
    ((HoldNoteBinding)BindingInstance).ProgressCtrl = this.ProgressCtrl;
    }
    BindingInstance.Keysound = this.DefaultNoteSound;
    BindingInstance.playOnceCtrlRef = this.playOnceCtrl;
    BindingInstance.spritePlayCtrlRef = this.spritePlayCtrl;

    BindingInstance.ExciteIndicatorRef = ExciteIndicatorRef;

    BindingInstance.IndicatorRef = IndicatorRef;
    }
     
    Nith666 likes this.
  5. Nith666

    Nith666

    Joined:
    Aug 1, 2012
    Posts:
    56
    I have the exact same issue, also on an iPad Air. So far I have now idea what the reason is, but I will continue investigating. The overhead spikes don't occur on iPhone 5s or 6s
     
  6. Nith666

    Nith666

    Joined:
    Aug 1, 2012
    Posts:
    56
    I think I've found the reason. You can probably safely assume that overhead is in most cases related to vsync. On iOS devices this can't be turned off. So when the stuff you do during one frame exceeds the frame time like 33ms for 30FPS, the device waits for the NEXT vsync, which at least in my case causes the big amount of overhead. I'm just a little bit over the 33ms which causes a wait as if the frame rate was set to 15FPS. Will now try to increase speed to get below 33ms
     
  7. Neonlyte

    Neonlyte

    Joined:
    Oct 17, 2013
    Posts:
    513
    Thanks for the reply.

    This is exactly what I encountered. My code was not efficient enough and it caused a spike to break the V-sync and Unity Player had to self-adjust which is another spike.

    I have improved my code so spikes have not appeared since then. :)