Unity new Input System : Progress Bar Charge (Part X)

Matteo Lo Piccolo
5 min readJan 3, 2022

--

Another useful method when we use the new input system is, for example, to create a Charging Bar.

What we want here is: when we press the button, the bar is loaded, we release the button, the bar become empty.

We create an easy set up , with UI with a Slider

I delete the “Handle Slide Area” inside the Slider

Delete Handle Slide Area
Now we have this

Then in Fill Area, we change right from 15 to 5, so we can full all the bar

Now, we create a classic Input Actions from the assets menu

The key binding for SlideFill is the Space Bar

As always we take everything really easy so we can test it without problems.
I call my Action Maps UI, my Actions SliderFill and in Properties I use a Button.
Until now, nothing new.

The interesting part is this : in Interactions, we press + and this time we use “Press”

At this point, we have UIImputActions and we genarate the C# file, what we need is a script for the Slider.
I called mine SliderFill, feel free to change it but watch out, don’t call it “Slider” because it can give you some error or problems
(this because inside UnityEngine.UI there is already “Slider” name)

Now we need some reference, one as always for the UIInputActions, other for the Slider, because we use UI.
So, we add “using UnityEngine.UI” at the top, then
[SerializeField] the Slider so we can manage it in the editor.

And in “Start” we initialize UIInputActions and make it Enable(),
for the Slider we need to take the component (this script is attached directly at the Slider, if we attached it to the Canvas we need to use GetCompontInChildren<>())

In this specific test, we use another two events : started and canceled.
The logic for this two things is this :
started is when we press the button,
canceled is when we release the button.

So, in practice, in started we fill the progress bar, and in canceled we empty the progress bar.

Ok, let’s write some logic for this behaviour!

First, we add both events

Now, a simple but good way to test it, is use a Coroutine.

What happen here is really simple, we take the slider.value and we add 1.0f every frame (yield return null it means wait for the next frame)

NOTE : little tip for who doesn’t know it.
The slider value, in this case, goes from 0 to 1.
We add 1.0f every frame, multiply by Time.deltaTime.
Time.deltaTime, if I’m not wrong, depends by the frame rate of your computer.
And it gives you the time in seconds since last update.
60fps ~ 0.016, 30fps ~ 0.033.

So we can read this operation like this
add to slider.value a number like 0.something * 1.0f every frame.

If you want, we can make a little test

Play

In my case, the number is between 0.03 and 0.04.

In my PC the code running similar to this
slider.value + 0.035 * 1.0f every frame

More readable : slider.value + 0.035 every frame.

Back to our code.
The easy way to know when we press and when we release the button, is a boolean.
We add it at the top

bool _isCharging = false.

Now, we can manage the logic in many ways, as always, what I do here is :
in started, the bool become true and we start the Coroutine,
in canceled, the bool become false.
The part of logic is inside a Coroutine and we based it on the bool.
Nothing complex.

In started :
we press, boolean becoming true and the Coroutine Start()
In canceled :
boolean becoming false

In the Coroutine, instead, we have this

We need a while loop here, because the bar charge continuously “while” we holding down the button and the bool is== true, and empty the bar “while” the bool == false.

I hope this is clear.

And use while loop inside Coroutine is “safe”, because generally we use “yield return new WaitForSeconds(some value)”
and this is makes “Unity breathe”.
Here we have yield return null,
but we based while loop on the value of the bool.
In any case, always watch out when we use while loop.

If we test it

When we press the bar goes up, if we release the bar goes down.
Really good!

An alternative method is to change the second while loop inside Coroutine, and we can based it on the value of the slider and not on bool.

The logic in this case is:
as we press Space Bar, bool == true and Start Coroutine.

When we release Space Bar, the bool == false.

Now the second while loop is based on slider.value and automatically, when we release the Space Bar, slider.value is greater than zero.

Because if slider.value == 0, it means we’ve never pressed the Space Bar.
But if we press it, the slider is filling up.

It works in both cases, but is always fun too see how to solve problems in different ways.
This example is incredible easy, but even in more advence system or mechanics there is always more than one method to solve problems.

We see in the next articles!

--

--

Matteo Lo Piccolo

Always in love with programming, even if late (I'm already 39 years old) I decided to follow my dream! We will see how far my passion will take me!