Create Skippable Cutscenes in SpriteKit with Timing Functions
Cutscenes are a labor of love, so it is hard accepting that some people just don’t care. That story that took months to bring together may be amazing to you, but to others it is just an inconvenience. So, for that reason, we have to make cutscenes skippable. However, I didn’t want to just settle at skipping the entire scene. I wanted to also make it skimmable for the speed readers, or those who are mildly interested.
Watching the video above, you can see how skimmable cutscenes could bring about all sorts of complications. The worst of those challenges is how to handle placement of the camera. Take this example:
- 1. Camera starts zooming to character A
- 2. Dialogue A
- 3. Pan camera to character B
- 4. Dialogue B
How would you solve the problem if the user skips step 1 and 2? My first attempt was to store information inside of step 4 that contained the expected camera position. Then, if the camera wasn’t at that position, immediately jump it there. That solution worked just fine, but it caused me to duplicate the information. Step 3 and 4 both had to know the ending position of the camera.
An alternate solution to this problem is to use SKAction
and timingFunction
. When an action is running, it will immediately fast forward to the end when the timingFunction
returns 1. For example:
Now that we know how to end an action, the next step is to make it dynamic. In my findings, timingFunction
can not be altered once the action starts running. So, I had to make a class for each cutscene action, and use a member variable to determine when it should finish.
In the code above, the timing function will work as expected until the member variable finishEarly
is set to true. Once set, the SKAction
will instantly run to completion. This can be taken much further to accommodate sound, in game items, and other events. I plan to break it down one a line by line basis to give granular control. But, we’ve got a good starting point for now. The example below shows my original scene being skimmed, which saves 5 seconds off of reading time.
[…] Skippable cutscenes […]
This… is brilliant. I wasn't even aware of the timing function property of SKAction. Could this also be used to ease-in/ease-out actions? Thank you so much!!
Yep. Bunch of libraries on GitHub that have custom easing functions. You just set the timingFunction of the SKAction to one of those custom functions.