Huge framerate drops in an empty scene - what is going on?

I would really appreciate you guys helping me out with a baffling problem I am experiencing. I have a near-empty scene. It has one object, i.e., a ball bouncing in it, targeting 60FPS.

I am deploying this to iOS to run on iPhones and it works. Lo and behold, the ball bounces at 60FPS. Here it is running:

9682208--1380752--Untitled.gif

Below you can see it running in the profiler. Indeed, it renders within 16.6ms keeping the smooth 60FPS.

Okay, so here is the problem. As soon as I touch my screen on the iPhone, the framerate immediately halves to 30FPS causing significant lag in the game. Why is this happening?

You can see below in the profiler what happens when the screen is touched. For some bizarre reason, it is taking twice as long to render. It stays like this for a second, and then resumes to 60FPS. If I touch again, this reoccurs every time the screen is touched.

Please, someone tell me what is going on here?! Why is this happening? I was experiencing this in my real game and I thought it was an issue with my game’s complexity. So I created this new, empty project and the problem is still happening. So clearly it has nothing to do with my game or its logic.

Below are some details on the versions I am using and the devices I tested this on:

Unity Version: 2020.3.48:

  • iPhone 14 Pro (iOS 17.3.1): Issue occurs
  • iPhone 14 Pro Max (iOS 17.3.1): Issue occurs
  • iPhone SE 3rd Gen (iOS 17.3.1): Issue occurs
  • iPhone SE 1st Gen (iOS 15.8): Issue does not occur!
  • Google Pixel 7a (Android 14): Issue does not occur!

As you can see, this issue occurs on iPhone and not on Android. Weirdly, the only iPhone that did not experience this problem is the first-gen SE, which maintains a smooth 60 FPS. The others listed all experience this issue! I thought it might be ProMotion related but it happens on the third-gen SE too which is not ProMotion.

I have even attached the project package so you can see this for yourself. If someone could resolve this I would appreciate it more than you can imagine. It is causing horrible lag issues whenever the player touches the screen and interacts with my game on iPhone.


UPDATE:

Unity Version 2022.3.21f1:

  • iPhone 14 Pro (iOS 17.3.1): Issue occurs
  • iPhone SE 3rd Gen (iOS 17.3.1): Issue occurs
  • iPhone SE 3rd Gen (iOS 17.4): Issue occurs

9682208–1380746–BallBounce.unitypackage (4.1 KB)

WaitForTargetFPS is VSYNC.

You should look into your Application.TargetFrameRate, either in your project settings or in your script.

Thank you for replying, I really appreciate it. What do you mean by look into it? I use it as follows:

Application.targetFrameRate = 60;

As you can see, I use this to set the target frame rate. Are you saying this is wrong? How else can I ensure it runs at a smooth target frame rate?

Have you tested it with 2022 LTS? Those contain most of the fixes.
2020 LTS is End of Life if I’m not mistaken. So it won’t be fixed either way for that version.
If you really think it is a bug in the latest LTS then you should probably send a bug report with the specifics

I was avoiding upgrading to 2022 because it might break my project, but I guess I’ll need to do it sooner or later. I’ll give it ago and let you know what I find. Thanks for the recommendation.

Okay so I just updated to the latest LTS Unity 2022.3.21f1 and this issue is still happening in the exact same way. This is absolutely insane. How can the engine lag on mobile whenever you touch the display? Please someone tell me if you are also experiencing this issue?

Does it lag when you’re not using the profiler?

Based on your list, it’s only lagging on 17.3.1 iOS? It looks like 17.4 is out. Are you able to test on that iOS version?

Yes it absolutely does lag when not using the profiler. If I build it without selecting Development Build and do not run the profiler, this issue still occurs. It has been happening for months, continuously through 2020.3. Clearly it is still present in 2022.3 which means it was likely there in 2021 too, so it’s been years. I highly doubt it will suddenly be resolved in iOS 17.4 because it appears to be a Unity issue, does it not?

Do you have an iPhone? Maybe you could try it and see if you are having the same issue? I find it hard to believe that such a fundamental flaw exists and nobody is talking about it. So is it just me? I am very confused.

Which input are you using? Input Manager or the new Input System?

I am using Input Manager, not the new one. But, if you look at the package you will see in the script that the Input Manager class is never called. The application never reads a user input, all it does is bounce that ball up and down. Yet whenever the screen is touched, the framerate will be halved.

Also, I can confirm this issue using the in-built iOS graphics profiler (in Settings > Developer > Enable Graphics HUD). When the screen is not touched, it shows:

9685004--1381280--IMG_1821.PNG

As you can see a smooth 60 FPS. As soon as the screen is touched:

9685004--1381283--IMG_1822.PNG

You can see that it halves to 30 FPS. So it is being reported by the Unity Profiler and the built-in iOS one.

Yes, I work as a software developer and we don’t have this issue.
It doesn’t happen on Android and doesn’t happen on the older iOS version you’ve tested on. Which is why I was saying to check the iOS version. I’m not using 17.3.1 on my test device, but it wouldn’t be farfetched for an iOS version to have a bug. I’ve seen this happen before in a previous version of iOS and updating it fixed the issue. Just based on your own test, the thing they all share in common is iOS version.

I remember seeing a thread a while back where 60 would sometimes result in 59 for some devices and the fix was to just set it to 61.

You probably should get rid of that targetFrameRate setting all together. That’s because mobile devices always use vsync. When you artificially force a framerate of 60 (which means Unity does deliberately suspend the frame) even the slightest hardware delay can push it beyond the next v-sync.

Okay but then how do I ensure it runs at 60fps? If I don’t manually target it then the game runs at a choppy 30fps by default.

No, it does not. If it does you do too much within one frame so you exceed the 16ms per frame. Unity “usually” simply runs as fast as it can. However if vsync is enabled, whenever a frame has finished, it waits for the next v-blank to update the screen / flip the buffers. If your load is below 16ms your frame should be ready when the device does it’s vertical sync. The only unpredicable things that can cause issues are the garbage collector or other external influences. Have you used the profiler to see where your frame time is spent?

In my own experience with mobile devices, it does. Not setting the targetFrameRate will usually result the device into running at 30 fps by default.

although 0 is the default, you might want to try this

QualitySettings.vSyncCount = 0

V-Sync is forced on mobile platforms. It even says so that it will be ignored in the documentation you’ve linked

Yes, that’s true. However I didn’t think about the default limitation. Though my objection was mainly against the choppy framerate. As you said, by default it’s just limited to a steady 30 in many cases unless you cause hicups which could make it skip one or two frames and make it choppy.