The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →A one-button timing game only works if the game agrees with the player about when the tap happened. In Unity, that means reading the tap in the input path that runs before Update, recording the time of the press, and judging it against elapsed time rather than a count of rendered frames. Keep FixedUpdate out of tap handling. “One Perfect Tap” is used here as the name of a tutorial concept, not a released game, and nothing below reports a build, device test, or measured latency.
The loop you are building
The game needs only six steps, and each one maps to a specific engineering decision:
As an Amazon Associate I earn from qualifying purchases.
- Animate a target marker using elapsed time, so its position depends on how long the game has run, not on how many frames have been drawn.
- Receive a tap and capture the time it was handled.
- Calculate the signed difference between the tap time and the moment the target was meant to be on the mark.
- Compare that difference against a success window you define.
- Update the score or feedback (a sound, a flash, a miss indicator).
- Reset the target or advance to the next beat.
Every later section explains one of these steps. The most common bug in a project like this is mixing them up: judging the tap in the same place that moves the target, or letting a physics callback drive scoring.
Choose the right loop for each job
Unity’s Manual describes Update as per-frame processing and FixedUpdate as a callback on a fixed interval, used mainly for physics. FixedUpdate can run zero, one, or several times within a single rendered frame, depending on timing and the simulation’s need to catch up. A tap game that treats it as “one reliable callback per screen frame” will drift in exactly the moments where timing matters. Unity’s scripting reference for MonoBehaviour.FixedUpdate states: “Use FixedUpdate to perform physics system calculations.” If your prototype has no physics, the fixed loop is probably unnecessary for the basic timing and scoring logic.
#1 Best Overall
| Job in the tap loop | Where it belongs | Reason |
|---|---|---|
| Detecting the tap | Input System event processing (in the default mode, immediately before Update) |
The press is delivered into the same frame flow that Update reads |
| Moving the target | Update, driven by elapsed time |
Frame durations vary, so position must derive from time rather than a fixed step per frame |
| Judging and scoring | Update, immediately after tap detection |
Keeps the judgment in the frame where the press was seen |
| Physics-driven objects, such as a bouncing ball | FixedUpdate |
This is the job Unity’s reference names for the fixed loop |
The reference pages are linked here for the wording: Unity Fixed updates (Manual, 6.0), MonoBehaviour.FixedUpdate scripting reference, and Unity per-frame updates.
Reading the tap: Input System update modes
The Input System decides when queued input events are processed, and that choice has to match the code that consumes them. The InputSettings update mode documentation for Input System 1.4.4 lists three options. The default is dynamic processing. Pick one deliberately and keep it consistent with your reading code.
Rank #2
| Mode | When events are processed | What to watch |
|---|---|---|
| Process events in dynamic update (default in 1.4.4) | Immediately before each Update |
The simplest pairing for a tap game that reads input in Update. Recommended starting point. |
| Process events in fixed update | Immediately before each FixedUpdate |
Use only if you intentionally align input with the fixed loop. Querying input in the wrong update state can produce errors in the Editor and development builds. |
| Manual | Only when your code calls the input update explicitly | If the update is not called, events can accumulate or be lost. Avoid this for a beginner tutorial unless you accept that responsibility. |
Reference: Input System UpdateMode (1.4).
Timing without counting frames
Capture the time at the tap
Time values in Unity are tied to the frame loop. Reading Time.timeAsDouble inside Update gives the time at which the game handled the press, which is quantized to the rendered frame. Whether that matters depends on how narrow your window is. Measure the difference on target hardware instead of assuming it is negligible.
Free tools Windows power users keep installed
One-click scans. No signup required.
Compare the tap against a window
Store the moment each beat should land. Judge a tap by the signed offset from that moment, accept it when the absolute offset falls inside the window, and count a miss when the window closes without a tap. The starting values below are for illustration only; the window width is a design decision to tune through playtesting, and no recommended width is established by the engine documentation.
using System;
using UnityEngine;
using UnityEngine.InputSystem;
public class OnePerfectTap : MonoBehaviour
{
[SerializeField] float beatInterval = 1.0f; // seconds between target arrivals
[SerializeField] float windowSeconds = 0.08f; // full width of the accept window
double nextBeat;
void Start() => nextBeat = Time.timeAsDouble + beatInterval;
void Update()
{
double now = Time.timeAsDouble;
double half = windowSeconds / 2.0;
// Close the window if the beat passed without a tap.
if (now > nextBeat + half)
{
Debug.Log("Miss: no tap in window");
nextBeat += beatInterval;
}
if (!Pressed()) return;
double offset = now - nextBeat; // signed seconds from the target moment
if (Math.Abs(offset) <= half)
Debug.Log($"Hit, offset {offset * 1000:F1} ms");
else
Debug.Log("Miss: tap outside window");
nextBeat += beatInterval;
}
static bool Pressed()
{
if (Touchscreen.current != null)
return Touchscreen.current.primaryTouch.press.wasPressedThisFrame;
return Pointer.current != null && Pointer.current.press.wasPressedThisFrame;
}
}
The script falls back to the pointer when no touchscreen is present, which makes Editor testing with a mouse straightforward. The target's visual position should be computed from the same nextBeat clock so that what the player sees and what the code judges cannot drift apart.
Keep two thresholds separate
The Input System exposes a configurable maximum delay between press and release for an input to qualify as a tap, through the InputSettings API. That is a gesture-recognition rule that answers "was this a short press?" Your "perfect" window answers a different question: "when did this tap land relative to the beat?" Tuning one does not tune the other. If a long press is not registering as a tap, adjust the recognizer setting; if hits feel too strict, change windowSeconds. Reference: InputSettings API (1.4).
Rank #4
Frame rate and target platform
Setting Application.targetFrameRate requests a render cadence; it does not guarantee that the device will reach it. Runtime platform and hardware determine what is achieved. The Unity 2023.2 scripting reference describes platform-specific behavior, and the relevant points for this game are:
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware match- On mobile platforms,
Application.targetFrameRateis the control used, andQualitySettings.vSyncCountis ignored. - On desktop, the reference favors vSync for smooth pacing, and the achievable rate depends on platform and device capability.
- Default values and high-refresh behavior vary by version and platform, so check the documentation for your exact Unity version.
Reference: Application.targetFrameRate (2023.2). Because the timing logic above is driven by elapsed time, a variable frame rate changes how smoothly the target moves, not what time a tap is judged against.
Best Value
Test the timing before you tune it
- Record the target platform and Unity version, and write them in your setup notes.
- Confirm which input update mode is active and that the reading code runs in the matching loop.
- Log the signed offset of every tap, not only hits and misses, so you can see whether errors cluster on one side of the beat.
- Test on the actual target device with the frame rate you intend to ship, and repeat the test after changing the render settings.
- Adjust the window only after a playtest session produces offset data, and document the value you chose and why.
What the sources do and do not establish
The guidance above comes from Unity's official documentation: the Manual pages for fixed updates and per-frame updates, the Input System 1.4 API pages, and the 2023.2 scripting reference for frame rate. These pages establish how the engine schedules input, physics, and frame-rate requests. They do not provide a recommended success-window width, a measured input latency, a frame-rate benchmark for any device, or a comparison of input modes for this specific game. Any numbers for those points have to come from your own build and test data.
The advice to keep input, timing, and physics separate applies whether the game is a phone prototype or a desktop build; the exact settings differ by platform and version, so verify them against the documentation that matches your project.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.




