Rendering & Graphics Issues May 24, 2026

Unity targetFrameRate Ignored on Menu Because vSync Overrides Fest FPS Cap - How to Fix

Fix Unity 6 fest demos where menu frame rate stays uncapped—vSyncCount vs targetFrameRate, scene profile swap, Deck verification, and menu_fps_cap receipt gates.

By GamineAI Team

Unity targetFrameRate Ignored on Menu Because vSync Overrides Fest FPS Cap - How to Fix

Problem: You set Application.targetFrameRate = 60 on the main menu scene, but the Steam FPS overlay still shows 118–120 on a Steam Deck OLED (or 144+ on desktop). Gameplay scenes respect your cap; the idle menu does not. Fest reviewers report fan spin before they press Start.

Who is affected now: Unity teams shipping May–June 2026 fest builds after the menu FPS cap opinion and the new Unity menu FPS tool resourcetargetFrameRate alone loses to QualitySettings.vSyncCount.

Fastest safe fix: On menu scene entry → QualitySettings.vSyncCount = 0Application.targetFrameRate = 60 → on gameplay load → restore gameplay vSync policy and targetFrameRate → verify on installed Steam build with overlay FPS → file menu_fps_cap_receipt_v1.json.

Direct answer

Application.targetFrameRate sets a desired frame rate. When vSyncCount is Every V Blank (1), Unity waits for the display refresh—on a 120 Hz panel that becomes ~120 FPS regardless of your target. Fest menus need a MenuProfile: no vSync + explicit cap; gameplay keeps its own profile.

Why this issue spikes in May 2026

  1. Opinion + resource traffic — Teams added targetFrameRate without touching vSync.
  2. Deck OLED 120 Hz — Default test hardware for fest QA.
  3. Quality tier defaults — Project settings apply globally until scenes override.
  4. Duplicate OnEnable — Menu bootstrap scripts reset FPS after your cap runs.
  5. Editor vs Steam install — Play mode in Editor masks packaged behavior.

Symptoms and search phrases

  • targetFrameRate works in gameplay, not menu.
  • Steam overlay shows 120 FPS on static menu.
  • Laptop fan audible at title screen only.
  • QualitySettings.vSyncCount = 1 in Project Settings.
  • Third-party menu plugin sets targetFrameRate = -1 on enable.
  • URP post-processing on menu still runs at display refresh.
  • Development Build overlay shows triple-digit FPS on menu.

Root causes (check in order)

  1. vSyncCount = 1 (Every V Blank) overrides targetFrameRate.
  2. Menu scene never applies MenuProfile—only gameplay script sets FPS.
  3. OnEnable order—later script sets -1 (uncapped).
  4. Platform Quality tier re-applies vSync on scene load.
  5. Steam Deck reports refresh rate; cap not tested on device.
  6. URP render scale / frame pacing not the same as Application cap—still verify Application layer first.

Beginner path (one evening)

  1. Open Project Settings → Quality → note vSync Count per tier.
  2. Add MenuFpsCap.cs below to menu scene root.
  3. Build Windows fest demo → install via Steam (or local depot).
  4. Enable Steam overlay → FPS counter → idle menu 30 seconds.
  5. Copy numbers into menu_fps_cap_receipt_v1.json.

Working dev path

  1. Two presets: MenuProfile (vSync off, FPS 60) and GameplayProfile (project policy).
  2. Central SceneFramePolicy.cs on every scene transition—no scattered OnEnable caps.
  3. CI: fail if packaged build menu smoke exceeds 65 FPS max (scripted capture optional).
  4. Attach receipt to Wednesday smoke BUILD_RECEIPT row menu_fps_cap: pass.

Step 1 — Menu scene: disable vSync, set explicit cap

using UnityEngine;

/// <summary>Attach to a single root in MainMenu scene only.</summary>
public sealed class MenuFpsCap : MonoBehaviour
{
    [SerializeField] int menuTargetFps = 60;

    int _prevVSync;
    int _prevTargetFps;

    void OnEnable()
    {
        _prevVSync = QualitySettings.vSyncCount;
        _prevTargetFps = Application.targetFrameRate;

        QualitySettings.vSyncCount = 0; // Don't sync to 120 Hz display
        Application.targetFrameRate = menuTargetFps;
    }

    void OnDisable()
    {
        // Restore when leaving menu (scene unload also calls OnDisable)
        QualitySettings.vSyncCount = _prevVSync;
        Application.targetFrameRate = _prevTargetFps;
    }
}
Setting Menu (fest) Gameplay (example)
vSyncCount 0 1 or 0 per project
targetFrameRate 60 0 (uncapped) or 60/120 toggle
Proof surface Steam install Same build, different scene

Official references: Application.targetFrameRate, QualitySettings.vSyncCount.

Step 2 — Restore gameplay profile on scene load

Use one loader—do not rely on OnDisable alone if you LoadScene synchronously:

public static class SceneFramePolicy
{
    public static void EnterMenu()
    {
        QualitySettings.vSyncCount = 0;
        Application.targetFrameRate = 60;
    }

    public static void EnterGameplay()
    {
        QualitySettings.vSyncCount = 1; // or 0 for competitive titles
        Application.targetFrameRate = 0;  // project gameplay policy
    }
}

Call EnterMenu() from menu scene Awake; call EnterGameplay() from first gameplay scene Awake.

Rule: Never set global QualitySettings in a plugin’s Update()—only on scene boundaries.

Step 3 — Hunt duplicate caps

Search project for:

  • targetFrameRate = -1
  • vSyncCount assignments in menu UI plugins
  • Asset Store menu frameworks with “unlimited FPS” option

Disable or reorder scripts so MenuFpsCap runs last (Script Execution Order → +100).

Step 4 — Verify on Steam Deck and desktop

  1. Install fest_public build from Steam client—not Editor Play.
  2. Steam → Settings → In-Game → FPS counter → top-left.
  3. Idle main menu 30 s → record max FPS.
  4. Load gameplay → confirm gameplay policy unchanged.
  5. Optional: unplug power on Deck—battery test per menu FPS opinion.

Pass: Menu 60 ±2 FPS; gameplay matches your documented policy.

menu_fps_cap_receipt_v1.json

{
  "schema": "menu_fps_cap_receipt_v1",
  "build_id": "fest-demo-2026-05-24",
  "engine": "Unity 6",
  "fest_public": {
    "main_menu_max_fps": 60,
    "settings_menu_max_fps": 60,
    "gameplay_cap": "uncapped_vsync_on",
    "vsync_menu": false,
    "target_frame_rate_menu": 60,
    "verified_on_battery": true
  },
  "proof": {
    "steam_install": true,
    "platform": "steam_deck_oled",
    "menu_idle_seconds": 30,
    "observed_menu_fps_max": 59,
    "observed_gameplay_fps_max": 118
  },
  "promotion_allowed": true
}

Store beside BUILD_RECEIPT.

Proof table

Check Tool Pass
Menu cap applied MenuFpsCap or SceneFramePolicy Code review
Packaged build Steam installed depot Not Editor only
Menu FPS Steam overlay ≤ 62 max idle
Gameplay policy Same build, level 1 Matches design doc
Receipt JSON on promotion PR promotion_allowed: true

Prevention

  1. Branch policy: menu FPS opinion linked in README.
  2. Bookmark 14 Unity menu FPS tools resource.
  3. Wednesday smoke F4 gate—menu idle before metadata promotion.
  4. Never ship Development Build to fest with FPS counter visible.
  5. Separate internal uncapped menu profiling from fest_public.

Troubleshooting

Symptom Fix
Still 120 FPS on menu Another script resets FPS—execution order
Cap works in Editor, not Steam Test installed build; check Quality tier for Standalone
Menu stutters after cap Try targetFrameRate = 60 with vSyncCount = 1 on 60 Hz desktop only—Deck still needs vSync 0
Gameplay now capped wrong Gameplay scene missing EnterGameplay() call
URP GPU still busy Reduce menu post-processing; cap fixes present/wait, not GPU cost entirely
Steam overlay shows 0 Enable overlay; use external cap tool only as secondary proof

FAQ

Should menu use vSync on 60 Hz monitors?
You can use vSyncCount = 1 only if display is 60 Hz and you accept vsync input feel. On 120 Hz Deck, use vSync off + targetFrameRate 60.

Is 120 FPS on menu ever OK?
Not for fest_public retail demos per site opinion—use internal branch for profiling.

Does this replace GPU optimization?
No—cap stops pointless present loops; still optimize menu blur/VFX.

URP 17 pink on Deck?
Separate issue—see URP stylized lit pink on Deck fix after FPS cap passes.

Overlay shows 60 FPS but Deck still drains on idle menu?
See Deck OLED idle menu battery drain fix—run 15-minute power smoke and idle_power_smoke_pass.

Related links

Cap the menu on the Steam install players actually download—not the Editor tab you live in during crunch week.