Skip to content

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.

We typically consider two different ways of nudging or punching (we’ll use these terms interchangeably):

  1. 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.
  2. 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.

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));
MethodWhat 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

The UI equivalent, working in anchored position:

MethodWhat 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.

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.