Best way to do a smooth rotation (with wrap) based on collision input?

I’ve been trying to implement a blueprint where I can shoot at a box and every hit causes that box to yaw by x degrees, with yaw over 360 wrapping back to 0. I also want the box to smoothly rotate from the previous position to the new position when I shoot it, not just snap to the next location. But, if the box hits the next x degrees, it should stop and wait until it is shot again.

Logically, this doesn’t feel like a hard problem but I’ve been having a lot of problems getting it to behave exactly like I want, so I was hoping someone might be able to shed some light on what I’m doing wrong. Or propose a completely different approach that’s better. Whatever works, really.

Here’s my basic idea so far:

  1. There’s an array of floats that represent my discrete yaws. So, if I want the box to have 4 spin positions, the array would hold 90, 180, 270, 360.

  2. I have an Event Hit node that makes sure that what hit the box is the desired projectile. Then, it makes sure that the box isn’t already in a rotation by checking a rotation bool. If it isn’t, it will increment the array indexer (or wrap back to 0 as necessary), and then set the rotation bool to true.

  3. I have an Event Tick node that will check to see if the rotation bool is set. If it is, it will lerp between the current yaw and the yaw in the float array at the current indexer value, using the delta time as the alpha. If the post-lerp yaw is within an acceptable tolerance of the array value, the yaw will be snapped to that value. The rotation is set, and if the value was snapped, the rotation bool is set false.

For some reason, after the third click (regardless of how many spin values are in the array), the box gets stuck and won’t rotate any more. I previously checked to make sure that the accumulated delta time had hit 1 before checking to see if the yaw was near the array value, but that created issues with re-activation delay. And, it shouldn’t be necessary. Empirically, I shouldn’t be able to shoot it multiple times with expected results before it craps out if it was.

Here’s my detection routine:

Here’s my rotation routine:

So, that’s where I’m at. Hopefully this isn’t too much of a wall of text and it all makes sense. Please help?

Thanks!

I’ll just answer my own question; maybe someone else will find this useful later.

The solution was that I did indeed want to make sure that the accumulated delta time had reached 1 before continuing logic. And that makes sense, because lerp operates between 0 and 1. Why it seemed problematic before, the re-activation delay, was because I wasn’t lerping between two fixed points. By making the A value of the lerp the current actor rotation, the starting bound was constantly sliding and each tick the lerp got slower until it finally reached one. There wasn’t re-activation delay so much as the lerp took much longer than I assumed it should to complete. The easy fix here was to track the previous array index and use that as the starting bound for the lerp.

Reworking for that created a flawlessly working Blueprint, and much simpler graphs.

The new detection routine:

The new rotation routine: