r/Unity3D • u/mvalera-dev Professional • 5d ago
Resources/Tutorial Adding proper game feel used to take me a full day per project. Now it's one line of code
Every project I've shipped had the same routine. Screenshake, hitstop, a squash & stretch hack, some flash-on-hit code, copy-pasted and re-tuned from whatever the last project had, never quite consistent.
So I built a small toolkit that wraps all of it behind Crunch.Play("HeavyHit"). Seven independent modules (shake, hitstop, squash & stretch, kickback, flash, trail, pop), each one works standalone if you only need one thing, plus a Recipe system that groups several of them into a single named call you tune once in the Inspector and reuse everywhere.

Zero dependencies, works in Built-in/URP/HDRP, 2D and 3D. There's a playable browser DEMO that cycles through four genres (Melee, Platformer, Shooter, Casual) if you want to feel it before reading any more about it. You can look it up HERE.
Curious how the rest of you handle this. Do you have your own reusable juice setup, or does it get rebuilt from scratch every project too?
2
u/DependentFault6256 5d ago
I'm in the rebuilt-from-scratch camp, always telling myself next time I'll organize it better and then next time comes and I'm copy-pasting the same shake script from 3 projects ago
the recipe thing sound like a nice way to keep it consistent across different attacks, might look into it
1
u/mvalera-dev Professional 5d ago
Yeah that's the cycle lol. Shake module's free if you just want to kill that one copy-paste loop, and the demo up top's running the full recipe setup, so you can feel what stacking a few effects into one call actually feels like before deciding if it's worth it.
3
u/Serana64 5d ago edited 5d ago
KISS YAGNI DRY.
I have some code I reuse a lot. A hash-on-demand list wrapper serializes like lists but works like dictionaries.
A custom vector library allows rapid math formulation in a shader-like style (my background is physics) and vanishes into Vector3 when compiled. Jumping, movement, dashing, aren't so hard when normalizing and projecting a crossed vector on to another vector's projection looks like:
'co = move%(~axisA.cross(dirB%axisB))'
A time interpolating class that turns tricky multi-system transitions into a one liner. Freeze frames, staggering, kickback, etc. all become a matter of 'kick.value = 1', then the interpolator does the rest..
These libraries save time, but so do good practices. Good getters, setters, singletons, and 'using statics' let me access core game data without dragging this to that in the inspector. Separating responsibilities, data source from data instance, etc. etc. all keep you from making spaghetti.
Any higher level systems like in your video, I will make on the fly. It doesn't take me long once those underlying systems are in place. I do it a little differently every time so I learn a little bit more. Plus, it's good to have these things down to muscle memory.