According to Application.targetFrameRate and QualitySettings.vSyncCount docs:
QualitySettings.vSyncCount = 1;
syncs the frame rate to the screen's refresh rate. This won't work if VSync is switched off in the video driver. Another issue here is that many screens today work at 120Hz or 144Hz.
Application.targetFrameRate = 60;
sets the framerate at which Unity tries to render your game. So this is the right way to go for you. But, if you set QualitySettings.vSyncCount
to anything but 0, Application.targetFrameRate
is ignored by Unity. Exceptions are mobile platforms, where vSyncCount
has no effect at all instead, and VR platforms, where both values are controlled by VR SDKs.
So, you need to set your vSyncCount to 0. Addition: some people report that this doesn't work when called from Awake
. While this is not something I experienced, it is probably best to call it in Start
.
void Start() {
QualitySettings.vSyncCount = 0;
Application.targetFrameRate = 60;
}
Also note that this might not result in the desired effect when running in Editor, make a build to test it.
A good idea is to try this out in an empty project. This way you will know whether there's something to do with how Unity handles things, or the problem is in your real project code/setup.
There is also another technique to limit the FPS. Personally, I don't recommend it over the "official" way. It is best to find out why Application.targetFrameRate
doesn't work for you. But if nothing helps, here it is:
const int _fpsLimit = 60;
const double _desiredSecondsPerFrame = 1.0 / _fpsLimit;
void Update() {
var startOfFrameTicks = DateTime.Now.Ticks;
while (true) {
Thread.Yield(); // This call lets something else outside of your game to execute instead of this thread
// Then we return back and check whether we need to wait more or exit the loop
var currentTicks = DateTime.Now.Ticks;
var elapsedTime = TimeSpan.FromTicks(currentTicks - startOfFrameTicks).TotalSeconds;
if(elapsedTime >= _desiredSecondsPerFrame)
break;
}
}