Skip Cutscenes Button
Here's my simple tutorial about how to create a "Skip Cutscenes button" in Unity (the logic applies to any other engine too). You can find below the code and the download links.
How it works
The script uses Unity's Image.fillAmount (which is already clamped to [0, 1] by the engine) as the progress value. Each Update frame, it increases fillAmount by activeSpeed * Time.deltaTime while the key is held, or decreases it by cooldownSpeed * Time.deltaTime when it isn't. Once fillAmount reaches exactly 1, the skip function fires once (guarded by a bool flag so it only runs once). The button also scales from its start size to targetHolderScale using an EaseIn curve (fillAmount * fillAmount) so it feels snappier at the end.
The whole thing is about 30 lines of C#. The activeSpeed and cooldownSpeed are separate values so you can tune how fast the button fills vs. drains - a common pattern is to make cooldown slightly faster than fill (here it's 0.5 fill vs. 0.6 drain) to add a bit of urgency.
Download
You can download the free UI "Prompts Pack" clicking here, created by @Xelu.
Code
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Assertions;
public class HandlerScript : MonoBehaviour
{
//The circle that shows us the overall progress
public Image fillImage;
//Holder of the entire button, used to change its scale
public RectTransform holderRect;
//Start scale of the holder
Vector2 startHolderScale;
//The desired scale we want when we complete the input, i.e. the input percentage is 1
public Vector2 targetHoldercale = new Vector2(1.2f, 1.2f);
private void Awake()
{
//Assures we don't have null references
Assert.IsNotNull(fillImage);
Assert.IsNotNull(holderRect);
startHolderScale = holderRect.localScale;
fillImage.fillAmount=0;
}
//The key we want to press
public KeyCode keyCode = KeyCode.X;
//Speed that increases the progress if we press
public float activeSpeed = .5f;
//How fast the progress decreases if we don't press the desired key
float cooldownSpeed = .6f;
//Prevents the function to be executed more than once
bool functionTriggered = false;
void Update()
{
//Increases or decreases our progress based on our input (and if we didn't already trigger the function)
//No need to clamp, since fillAmount is already clamped by Unity in the [0,1] range
fillImage.fillAmount +=
((Input.GetKey(keyCode) && !functionTriggered) ?
activeSpeed :
-cooldownSpeed) * Time.deltaTime;
//Changes the size of the button based on our progress
holderRect.localScale = Vector2.Lerp(
startHolderScale,
targetHoldercale,
fillImage.fillAmount * fillImage.fillAmount //you can apply an interpolation there, I applied EaseIn
);
//Triggers the function if we didn't already, and the progress/percentage is 1
if (!functionTriggered && fillImage.fillAmount == 1)
{
functionTriggered = true;
Debug.Log("Button pressed completely");
//Do something here
//Skip cutscene or similar
//[...]
}
}
}
Frequently asked questions
Can I use a gamepad button instead of a keyboard key?
Yes, swap Input.GetKey(keyCode) for the equivalent gamepad input via the Input System's Gamepad.current API, or assign a gamepad button to a KeyCode in the old input manager.
Why does the cooldown use a different speed than the fill?
It's a design choice. Having the drain slightly faster than the fill (0.6 vs 0.5 here) means the player needs to hold the button fairly consistently, which avoids accidental skips and gives a better feel.
How do I prevent the button from triggering twice?
The functionTriggered bool guards against that. Once set to true, neither the fill check nor the scale update can fire the action again until you reset it manually.
Can I reuse this for anything other than cutscene skipping?
Yes, the "hold to confirm" pattern works for any action you want to require deliberate input: deleting a save file, reviving a teammate, opening a chest. Just put whatever you want in the //Do something here block.
Comments