Nudges and Punches (Free Game Polish!)
The term “nudge” refers to pushing a spring to trigger a reaction from it. As we learned earlier, springs don’t have a fixed state; we can alter the Current Value or Velocity at any time, and the spring will react and adapt to the change without issues. This ability to nudge the springs gives us the opportunity to add a lot of polish and liveliness to our projects with just a single line of code.
Two ways to nudge a spring
Section titled “Two ways to nudge a spring”We typically consider two different ways of nudging or punching (we’ll use these terms interchangeably):
- SetCurrentValue: By instantly changing the Current Value using the SetCurrentValue method, we can ensure that the Target is different from the Current Value, thereby guaranteeing that an animation will occur. There are some examples of this in the Demo. For instance, in an action game where characters can get hit, we could set the current value of the object’s scale on the frame it’s hit, causing the object to grow and then animate back to its resting state.
- AddVelocity: Similarly, using the AddVelocity method will cause the spring to move. If the spring is at rest with a velocity of 0, it will animate out of the resting state and eventually return to rest. If the velocity was non-zero, it will still influence and nudge the spring in a satisfying way.
Ready-made punches and shakes
Section titled “Ready-made punches and shakes”You rarely need to write those calls by hand. The toolkit ships the common punches as extension methods, so they appear on the component itself with no setup and no extra reference:
transformSpringComponent.PunchScale(0.5f);transformSpringComponent.PunchPositionVertical(3f);StartCoroutine(transformSpringComponent.ShakeRotation(magnitude: 20f, duration: 0.4f));On TransformSpringComponent
Section titled “On TransformSpringComponent”| Method | What it does |
|---|---|
PunchScale(baseScale, multiplier = 1) | A uniform scale punch. The classic “it got hit” pop |
RandomPunchScale(magnitude) | A scale punch in a random X/Y direction, so repeats don’t look identical |
ShakeScale(magnitude, duration, frequency = 40) | Keeps punching the scale for a duration. A coroutine, start it with StartCoroutine |
PunchRotation(baseRotation, multiplier = 1, randomDirection = true) | A twist around Z. Clears the existing rotation velocity first, so rapid repeats stay controlled |
RandomPunchRotation(magnitude) | The same twist, with a random sign |
ShakeRotation(magnitude, duration, frequency = 40) | Alternating twists for a duration. Coroutine |
PunchPosition(direction, magnitude) | A shove along any direction you pass |
PunchPositionVertical(magnitude) | A shove straight up |
PunchPositionHorizontal(magnitude) | A shove to the right |
RandomPunchPosition(magnitude) | A shove in a random direction. Returns the direction it picked, in case you want to match a particle or a sound to it |
ShakePosition(magnitude, duration, frequency = 40) | Positional shake for a duration. Coroutine |
On AnchoredPositionSpringComponent
Section titled “On AnchoredPositionSpringComponent”The UI equivalent, working in anchored position:
| Method | What it does |
|---|---|
PunchPosition(direction, magnitude) | A shove along any direction |
PunchVertical(magnitude) | A shove up |
PunchHorizontal(magnitude) | A shove right |
RandomPunch(magnitude) | A shove in a random direction |
Shake(magnitude, duration, frequency = 40) | Shake for a duration. Coroutine |
The three shake methods are coroutines because they punch repeatedly over time: roughly duration * frequency punches, each one in a direction chosen to oppose the last so the motion reads as a shake rather than a drift. They zero the velocity when they finish.
None of these do anything the two methods above can’t. They are the calls you would have written yourself, already written and named.
See it in the Demo
Section titled “See it in the Demo”Exploring the Demo examples is the best way to see all of these concepts in action and gain a deeper understanding of how nudges and punches can enhance the game juice of your projects.
