Anas iqbal
Anas iqbal

Reputation: 1044

Inconsistent jitter in iOS game

I am working on a very simple vertical scrolling game for Unity iOS. My game is experiencing inconsistent jittering. I have searched the web extensively looking for a solution without any luck. I am using Unity version 5.3.4 f1.

The Game

Gameplay screenshot

The Problem

What we have tried

I am all out of ideas. Any help or pointer will be highly appreciated.

Thanks in advance.

Upvotes: 8

Views: 1504

Answers (3)

Damien Dessagne
Damien Dessagne

Reputation: 11

I came accross the very same problem recently. Exactly... A vertical scroller in Unity, with simple graphics, experiencing an inconsistent framerate on iOS only, sometimes, maybe related to input, maybe not.

Anyway, I finally found where the problem comes from. Try changing the rendering engine on iOS from Metal to OpenGL ES 2 or 3.

Hope this solves your problem too.

Upvotes: 0

Anas iqbal
Anas iqbal

Reputation: 1044

Thank you all for your time.

  1. No, it is not a floating point precession error.
  2. We are instantiating objects at run-time but when the problem occurred we switched to object pooling but it didn't helped.
  3. I have done thorough profiling, even remote profiling on a device and garbage collector was also not the issue.

After further research I have come across a BLOG POST, these guys were facing almost a similar issue, and solution works in my scenario.

In short, the problem was with unity frame not syncing with device's frame drawing rate. When Unity takes a little longer to render its frame the device render loop will not wait for unity to finish and draw an empty frame which results in jitter. But, as I have said in the title of the post "Inconsistent Jitter", the blog also reports the same and so it does not happens all the time.

How do you know is it is the same problem? Well, you will see Render spikes in the profiler (although we had very minimalistic geometry). It will look more like that the Render is going mad.

Although the blog is more about Input getting laggy but It also helped in my scenario. Some might not understand how exactly to solve this issue for them I recommend this POST, which presents a much clear solution.

For further study, start reading when user named "cgJames" jumps into the CONVERSATION.

I hope this helps other as well.

Upvotes: 1

Xander Luciano
Xander Luciano

Reputation: 3893

This could be caused by a lot of different reason, and without seeing any code I can only make a few suggestions that come to mind:

1. Float point precision error

  • Is the character constantly falling?
  • Does the error occur after the character has fallen for awhile?

That would point to a floating point precision error. instead of having the character fall, move the objects around the character from beneath screen view to above screen view so that everything occurs near the origin.

2. Instantiating often or other lag spikes

  • Are you instantiating objects or pooling them?
  • Are you performing any long calculations?
  • Do you have a lot of for/foreach/while loops?

Instantiating will cause a lag spike and create garabage that will cause the garbage collector to run more often. Since the framerate is fixed, when a slow operation occurs you'll see some jitter.

Instead of Instantiating and destorying objects when the player goes some distance, you should Instantiate a pool of GameObjects after the scene loads, make them inactive with gameObject.SetActive(false), and store them in a list, array, etc. and when you need to Instatiate a new object, simply grab one from the pool, and change it's Transform.position and gameObject.SetActive(true) when it's needed.

3. Garbage collector running often

This one is unlikely to be an issue, but still mentioning it. take this example code:

void Update()
{
    Vector3 someVector = new Vector3(0,0,0);
    float distance = someVector.magnitude;
    if (distance > 5.0f)
        Vector3 someNewVector = someVector + transform.position;
    else
        Vector3 someNewVector = Vector3.zero;
}

Everytime Update runs, it creates new variables and allocates memory for them. Next time Updateruns, it creates new variables, and allocates more memory. Eventually, the memory usage sets off the garbage collector, which goes around and frees up the memory used by all the previousUpdate` functions. Instead, you should allocate the memory at the start, and then reuse the variables.

void Start()
{
    Vector3 someVector = new Vector3(0,0,0);
    Vector3 someNewVector = new Vector3(0,0,0);
    float distance = 0f;
}
void Update()
{
    someVector = Vector3.zero;
    float distance = someVector.magnitude;
    if (distance > 5.0f)
        Vector3 someVector += transform.position;
    else
        Vector3 someVector = Vector3.zero;
}

To diagnose this, you'd need to attach the profile debugger and watch and see if the jitter is consistent with the garbage collector.

Hopefully something here might be of some help to you. Your best bet for finding the source of the jitter is to use the profiler. Here's the instructions for iOS:

Connect your iOS device to your WiFi network (local/adhoc WiFi network is used by profiler to send profiling data from device to the Unity Editor). Check “Autoconnect Profiler” checkbox in Unity’s build settings dialog. Attach your device to your Mac via cable, check the “Development Build” checkbox in Unity’s build settings dialog, and hit “Build & Run” in Unity Editor. When app launches on device open profiler window in Unity Editor (Window->Profiler).

More info: The Profiler Window

Upvotes: 1

Related Questions