On this page

Viewport AutoPause — How It Works & FAQ

Under the hood

Viewport AutoPause is deliberately small. It hooks two engine signals and acts only when the idle/focus state actually changes:

  • Idle detection — a lightweight OnEndFrame callback compares the current time against FSlateApplication::GetLastUserInteractionTime(). When the gap crosses your idle timeout, it pauses; when input arrives, it resumes.
  • Focus detection — it listens to FSlateApplication::OnApplicationActivationStateChanged, so losing or gaining OS focus pauses or resumes immediately, independent of the idle timer.
  • Applying the change — on a state transition it iterates the editor’s viewport clients (GEditor->GetAllViewportClients()) and calls SetRealtime(bool) on each. This covers the 3D Level Viewports and asset-editor previews (Niagara, Material, Static Mesh, etc.) — which is what lets it pause running previews, not just the level view.

The common per-frame path does only a handful of cheap reads. The actual viewport iteration runs only on edge transitions — when you go idle or come back — so the plugin doesn’t add measurable cost while you’re working. The input preprocessor that tracks viewport interaction is only registered for the modes that need it (Aggressive and Maximum); in Standard mode it runs without one, so a keystroke or click pays nothing extra.

Why SetRealtime and not a temporary override?

Pausing uses a blanket SetRealtime(false) / SetRealtime(true) rather than a temporary realtime override. The override API only changes what IsRealtime() reports — it doesn’t stop the work. SetRealtime(false) is what actually unregisters the viewport’s active timer and halts the redraw/simulation loop, so it’s the only approach that genuinely stops asset-editor previews like Niagara from ticking.

A consequence worth knowing: because resume issues a blanket SetRealtime(true), a viewport you had manually switched to non-realtime will be flipped back on when the plugin resumes. That’s by design — Viewport AutoPause is a fully managed solution, and you hand it realtime control in exchange for not having to think about it. (Maximum mode and Sequencer playback are the two deliberate exceptions, where resume is targeted rather than blanket.)

How the framerate clamp works

Both the idle pause and the Active Framerate Cap work by managing the engine’s t.MaxFPS cvar, through a single owner so the two never fight:

  • While idle, it clamps t.MaxFPS to 3 — matching the engine’s own unfocused throttle — so the paused editor ticks cheaply while staying instantly wake-able.
  • While active with the cap on, it sets t.MaxFPS to your chosen ceiling, first clamped down to whatever the editor would run at anyway (the 120 default, the 60 battery limit, or any lower value you set yourself) — so it can only ever lower the rate, never raise it.
  • When it stops capping, it releases the cvar back to 0 (uncapped) rather than leaving a number behind, so the editor reverts to its own native baseline.

FAQ

Will it interfere with Play in Editor or Simulate? No. PIE and SIE are explicitly bypassed — the plugin never pauses or caps the frame rate while you’re playing or simulating.

Does it affect Movie Render Queue, Take Recorder, or rendering out a sequence? No. Movie Render Queue runs its own pipeline independent of viewport realtime state, and Take Recorder runs through PIE, which is already bypassed. Your renders are unaffected.

Does it slow down the editor while I’m actively working? Only if you ask it to. By default the active framerate cap is off, so viewports run exactly as they normally would and the per-frame check is just a couple of cheap reads. If you do enable the cap, that’s the whole point — it lowers the frame rate to save power, but never below a usable rate and never below what you’ve set.

Will the active framerate cap ever make my editor run faster — or get in the way? No. The cap can only ever lower your frame rate toward your chosen ceiling, clamped to what the editor would run at anyway. It’s off by default, ignored during Play/Simulate, and independent of the pause modes. See Active Framerate Cap.

Does it change anything in my packaged game? No. The module type is Editor, so the plugin compiles into editor builds only and strips entirely from cooked/packaged game builds. It has zero runtime footprint.

It paused while I was watching a Sequencer animation play. Why? With Pause Sequencer Playback enabled (the default), idle pausing also pauses actively-playing sequences. If you’re letting a long sequence play while reading elsewhere, either move the mouse occasionally, raise the idle timeout, or turn off Pause Sequencer Playback in Settings.

A viewport I’d set to non-realtime turned itself back on. Expected — resume issues a blanket SetRealtime(true). See Why SetRealtime above. If you want only the active viewport to wake, use Maximum mode.

How do I turn it off? Left-click the toolbar button to toggle it off. That choice is remembered per-user and persists across editor sessions, so it stays off until you toggle it back on. To remove the plugin entirely, disable it in Edit → Plugins.

Which engine versions are supported? Unreal Engine 5.7 and newer. It’s built and tested against UE 5.7.