
Unity Player Cannot Go Up Stairs Smoothly (3D Character Controller): Causes and Fixes
February 11, 2026
Unity 2D Lights Bug: Normal Maps Not Working Correctly (URP Fix Guide)
February 11, 2026Many Unity developers run into a confusing issue where OnTriggerStay() behaves inconsistently. Sometimes it fires continuously as expected. Other times it seems to skip frames, stop randomly, or not fire at all.
This is often described as an “OnTriggerStay bug,” but in most cases, the issue comes from physics timing, Rigidbody configuration, or collision setup.
This article explains why OnTriggerStay() behaves inconsistently and how to fix it properly.
What Is OnTriggerStay?
OnTriggerStay(Collider other) is called once per physics update while another collider remains inside a trigger collider.
Basic example:
void OnTriggerStay(Collider other)
{
Debug.Log("Object inside trigger: " + other.name);
}
Important: This method runs during the physics cycle, not every rendered frame.
Why OnTriggerStay Feels Inconsistent
Most inconsistency issues come from misunderstanding how Unity’s physics system works.
Problem 1: No Rigidbody Attached
For trigger events to fire, at least one of the colliding objects must have a Rigidbody attached.
If neither object has a Rigidbody, OnTriggerStay() will not work.
Correct setup:
- Trigger collider (IsTrigger = true)
- At least one object has a Rigidbody
Common mistake:
- Two colliders, both without Rigidbody
Problem 2: Rigidbody Is Set to Kinematic Incorrectly
If both objects are kinematic Rigidbodies, trigger messages may not fire consistently depending on movement method.
If you are moving objects manually using transform.position, physics may not detect proper trigger overlap.
Incorrect movement:
void Update()
{
transform.position += Vector3.forward * speed * Time.deltaTime;
}
Better approach:
void FixedUpdate()
{
rb.MovePosition(rb.position + Vector3.forward * speed * Time.fixedDeltaTime);
}
Problem 3: Physics Runs in FixedUpdate, Not Update
OnTriggerStay() is called once per physics step, not per frame. If your game runs at 120 FPS but physics runs at 50 updates per second, it may appear inconsistent.
Default physics rate:
Time.fixedDeltaTime = 0.02f; // 50 updates per second
This means OnTriggerStay() is called 50 times per second, not every frame.
Problem 4: Object Slightly Exiting Trigger
If your object vibrates or jitters at the trigger boundary, it may rapidly enter and exit the trigger.
This causes:
- OnTriggerEnter
- OnTriggerExit
- OnTriggerStay stopping briefly
Common causes:
- Physics jitter
- Low fixed timestep
- Incorrect collision shapes
Problem 5: Collision Detection Mode
Fast-moving objects may pass partially through trigger colliders between physics steps.
Fix:
- Set Rigidbody Collision Detection to Continuous
Problem 6: Disabling the GameObject
If either object is disabled while inside the trigger, OnTriggerStay() stops immediately.
This is expected behavior, not a bug.
Reliable Fix Patterns
Fix 1: Ensure Proper Rigidbody Setup
Correct trigger configuration:
- Trigger collider has IsTrigger enabled
- At least one object has a Rigidbody
- Movement handled in FixedUpdate
Fix 2: Track Stay State Manually
If you need stable behavior, track trigger presence yourself.
private bool isInside;
void OnTriggerEnter(Collider other)
{
isInside = true;
}
void OnTriggerExit(Collider other)
{
isInside = false;
}
void Update()
{
if (isInside)
{
Debug.Log("Still inside trigger");
}
}
This avoids relying entirely on physics callbacks.
Fix 3: Increase Physics Stability
- Enable Rigidbody interpolation
- Use Continuous collision detection
- Avoid moving objects using transform.position
Fix 4: Avoid Thin Trigger Colliders
Very thin trigger volumes increase the chance of inconsistent detection. Make triggers slightly thicker where possible.
Best Practices for Stable Trigger Systems
- Always use Rigidbody with triggers
- Handle movement in FixedUpdate
- Do not mix transform movement with physics objects
- Use Enter/Exit tracking for critical systems
- Test with slower physics timestep if debugging
Conclusion
OnTriggerStay() inconsistent behavior is rarely a Unity engine bug. It usually comes from physics timing, improper Rigidbody setup, or movement conflicts.
Understanding that trigger callbacks run in the physics loop, not per frame, is the key to solving most issues. With correct Rigidbody configuration, proper movement handling, and optional manual state tracking, trigger behavior becomes stable and predictable.
Proper physics discipline is essential for building reliable gameplay systems in Unity.










