Quick answer: Track presence with Enter/Exit + your own timer. Or set rigidbody.sleepThreshold = 0. Or make the body Kinematic.
Healing zone over a sleeping body. Heal stops firing. PhysX put the body to sleep, OnTriggerStay no longer ticks for it.
The Fix
public class HealZone : MonoBehaviour {
readonly HashSet<Health> _inside = new();
void OnTriggerEnter(Collider c) {
if (c.TryGetComponent(out Health h)) _inside.Add(h);
}
void OnTriggerExit(Collider c) {
if (c.TryGetComponent(out Health h)) _inside.Remove(h);
}
void FixedUpdate() {
foreach (var h in _inside)
h.Heal(Time.fixedDeltaTime * 10f);
}
}
Enter/Exit fire reliably regardless of sleep. Iterate the membership set on your own timer. Sleep stays enabled, optimization preserved.
Verifying
Body lies still in zone. Heal continues per FixedUpdate tick. With OnTriggerStay alone: heal stops once body sleeps.
“Track membership. Tick yourself. Sleep stays helpful.”
Related Issues
For BuoyancyEffector2D, see buoyancy. For CharacterController step, see step edges.
Membership set. FixedUpdate ticks. Heal flows.