# 7. Combat Feel Pitfalls
Part of [[Combat Feel and Hit Feedback]]. Prev: [[6. Worked Example Three-Hit Melee]].
## Leftover Animator triggers
`Attack` and `Hit` are consumed by a transition, but only if that transition runs. A death, a forced `CrossFade`, or a failed condition leaves the trigger set, and the next time you *can* transition you get a surprise swing. Reset triggers when leaving combat, on hit-react, and on death.
## One swing, many ticks
Causes, in the order you will hit them:
1. Hitbox left enabled into recovery.
2. `OnTriggerEnter` plus a query both applying damage.
3. `attackInstanceId` minted once in `Awake` instead of in `Activate`.
4. Two hitbox colliders on the same weapon, both live.
5. The movement capsule is also a hurtbox, and the blade overlaps it *and* the child hurtbox (if you forgot the matrix, you can even hit yourself).
Fix the pipeline, not the health bar.
## `OnTriggerEnter` on the enable frame
If the blade is already inside the hurtbox when you enable it, there is no enter event. Use the active-window overlap query in [[3. Hitboxes and Hurtboxes]].
## Animation events skipped by blends
`CrossFade` / a long transition can start a clip *past* the `Anim_HitboxOn` time, so the box never turns on (or never turns off). Keep combat blends short, plant a StateMachineBehaviour fallback, or also gate the box on a state tag + normalized time. Details in [[6.Animation Events Reliable Patterns]].
## `Time.timeScale` leaks
Always restore in `finally`. Cancel with `destroyCancellationToken`. Do not time the freeze with `WaitForSeconds` or `Awaitable.WaitForSecondsAsync` (both scaled). Do not use a global freeze for a hit that can land on 20 enemies in one frame - switch to a local `Animator.speed` clock. Setting `timeScale` to 0 is a pause, not a hit-stop; at 0, `FixedUpdate` stops (official docs). Never set `timeScale` from Editor code and forget it: the Editor itself will feel paused.
If you also scale `fixedDeltaTime` (the official slow-mo sample that keeps *real-time* physics), restore the saved value, not `0.02f` assumed. Designers change the project default.
## Input buffers on scaled time
A combo buffer or dodge cooldown that uses `Time.time` during hit-stop will stall. Use `Time.unscaledTime` for input forgiveness; use scaled time for movement that should freeze.
## Audio pitching and music
A global freeze can duck pitch on playing sources. Test with your mixer. The adaptive score in [[Music Mood Mixer]] should not hitch for 60 ms if you can avoid it - keep music sources on a path you have tested, or keep hit-stop short.
## Impulse on a VR rig
Do not shake tracked eye cameras on Quest. See [[Cinemachine 3]] part 7 and [[Meta Quest 2]]. Juice the weapon, the enemy, the off-HMD UI - not the visor.
## `Renderer.material` on a crowd
`material` instantiates. For many victims, use a `MaterialPropertyBlock` or a shader keyword. One dummy is fine.
## Knockback versus controllers
Adding force to a `CharacterController` without an accumulated external velocity does nothing visible. Fighting a NavMeshAgent without `Warp` leaves the agent snapping back. Hook the motor you actually shipped ([[Character Controllers]], [[NavMesh in Unity 6 (AI Navigation 2.x)]]).
## Networking
A client-side overlap is not authority. Confirm hits where [[Multiplayer with Netcode for GameObjects]] says they are confirmed.
## Tuning without a record
If you cannot say "the cancel opens at 12 frames, i-frames are 8, hit-stop is 50 ms," you are guessing. Record Play Mode or count `normalizedTime`. Feel is a measurement with an aesthetic on top.
## Sources
- `Time.timeScale` (6000.5): https://docs.unity3d.com/6000.5/Documentation/ScriptReference/Time-timeScale.html
- [[6.Animation Events Reliable Patterns]]
- [[3. Layers Matrix and Queries]]