Unity: High CPU on Small Projects


Quick Tip: I have been working on a TCP/IP Networking project using a client/server architecture. The client (and the server for that matter) are both relatively small code bases and the UI and object count are really low in the scene. I had been struggling with CPU load in the project and feverishly trying to work out why my code was baking the CPU (and GPU!). I’d assumed it was something stupid I had done in a loop with the networking structures I was not that familiar with. It’s really not easy to concentrate on new code when your laptop fan is literally screaming at you! I’d hit Play and the CPU would spike almost immediately. So I would switch to my local terminal and scrape through the open ports and network connections looking for a smoking gun. Turns out it was the default frame rate in the Editor trying to deliver the fastest graphics performance it could on my PC – and with such a low object count and and very simple graphics being asked for it was running like a Formula One race car when all I wanted was an old jalopy.

This is my CPU on Speed

Solution: Set Target Frame Rate!

A Unity project will attempt to run your project as fast as possible. Frames will be rendered as quickly as they can (limited by your display device’s refresh rate).

There are two ways to control frame rate:

Application.targetFrameRate – controls the frame rate by specifying the number of frames your game tries to render per second. (I wrote a script to use this – see below).

QualitySettings.vSyncCount – specifies the number of screen refreshes to allow between frames. (look for it in the Editor Settings). For a 60Hz display, setting vSyncCount=2 will cause Unity to render at 30fps in sync with the display.

Note that mobile platforms ignore QualitySettings.vSyncCount and use Application.targetFrameRate to control the frame rate.

The default value of Application.targetFrameRate is -1. (the platform’s default target frame rate)

I set mine using the script to 20 and when I hit Play got this result:

This is my CPU chilling out
using UnityEngine;

public class SetFrameRate : MonoBehaviour
{		
		[SerializeField]	// Just so you can check it in the inspector
		private int FrameRate = 20; // 20 is really low but got my CPU down to < 10% - 30 is the target for mobile and was < 20% CPU usage
		//private int FrameRate = -1; // reset to default
	
		private void Awake()
		{
			Application.targetFrameRate = FrameRate;
		}
}

I attached it to my Camera object.

Set Frame Rate

One interesting behavior of setting this using a script in Unity 2020.3.26f1 was that once it was attached to the Camera object and Play was initiated for the first time it must have set the frame rate somewhere internally in the Engine. When I removed the script (for testing) the frame rate did not automatically reset to -1. I had to re-attach the script and update it to set the frame rate back to the default. I had a search of the settings in the Inspector and Preferences and couldn’t find a visible reference to it anywhere so you have to be careful if you are going to put this on a Production build that you reset it before releasing otherwise you might end up with a lower frame rate than what the platform could achieve by default.

Enough procrastination – back to sockets, ports and buffers.

,

Leave a Reply

Your email address will not be published. Required fields are marked *