SFX: Anticipation – Freezing Time
In our previous post titled SFX: Anticipation – Adding Juice, we talked anticipation that is added ahead of an action to give it that extra punch. Then, we spoke about the techniques implemented, such as freezing time, which is our focus in this post. For Nebulas Lasso, we also want to add that juice to the UFO’s Special attacks to make them felt further. We began with freezing time. So, in this post will try and explain how to implement this in Nebulas Lasso.
In Unreal Engine 4, there is a function called GlobalTimeDilation, which gives the ability of manipulating length of a single Tick (Game Frame). For example, GlobalTimeDilation default value is 1, so if that value is reduced to 0.5, execution is slowed down by half. That yields a slowed down effect. The opposite is also true. Here is a great tutorial on how to use it. A complimenting function is also available, which is called CustomTimeDilation that modifies a specific Actor. This become useful when you need everything to slow down for the player ALONE, then you do a Global Time Dilation of value x, then do a CustomTimeDilation of value (1/x). Based this, to freeze time for ahead of an action, we use a GlobalTimeDilation. However, in our Game, we have several issues we had to deal with before freezing time would operate as we need it. The issues were mainly three; User-Input Buffering, UFO Movement and Nozzle Rotation to be Time based, transforming Firing Special Weapons to be a sequential waterfall execution that is placed within the EventGraph.
User-input buffering is the act of buffering is basically gathering and holding commands for delayed execution. This was needed to be added because User-Input in Unreal Engine 4, and in general, is asynchronously gathered, meaning, it follows no time frame, as soon as a user inputs a command it immediately fires the event.
When time is slowed down, so should User-Input, for that we added a buffer (array) to hold user input, and then executed as a bulk during each EventTick.
Buffered inputs getting executed in a bulk means that pressing left 3 times in a row will be executed in sequence within the same Tick. This yields sudden bursts of movement after the time stops freezing and returns to normal. To remedy this, we rewrote UFO movements and Nozzle rotations to be DeltaSeconds– the time duration since the past Tick until the current one. Therefore, if movement was 30 units per second, and time was dilated to be shorter, it will always be multiplied by the DeltaSeconds to yield the proper movement speed.
Finally, the need to implement firing special weapons to be in a sequential manner is a little indirect in affect. Say, we want freeze time for 1 second then unfreeze. This means we do it as follows:
GlobalTimeDilation(0.001) -> Delay(1 second) -> GlobalTimeDilation(1)
In Unreal Engine 4, Delaying time can only be executed in the EventGraph scope. So, if we use an Event to FireWeapons, but want to freeze time before the shot is actually fired, we must delay in between the User’s Fire command and the actual shot getting fired. For example, in Ryu’s Shinku Hadouken, a user will do the double quarter circles+punch, but before the Hadouken is thrown, the anticipation frames must be shown first.
Here are two videos showing examples of the special weapon not having an anticipation (first) and having it (second).
We understand that the impact is not as detailed as in MVC2 yet. But, if you compare you can observe the wind-up before the punch, so to speak 🙂
We expected this post to be more graphical than this. So, our apologies for this long wall of text… We will continue by implementing dimming of the everything aside from the executing Actor next. Please visit us again!