Blueprint Tutorial: Stamina Decay/Regeneration Implementation

Hi there!

Below is a tutorial i have put together for implementing a pretty basic stamina system into your project.
The tutorial is broken down over 15 steps which should hopefully help with any troubleshooting problems and generally i find i p to work in small chunks of work.

This tutorial is intended to be completed after my previously submitted Sprinting Tutorial however the sprint function has changed quite drastically between the two tutorials so this is not necessary but is recommended if you are maybe unfamiliar with setting up a project and working in the event graph.

Throughout the tutorial, i have hyperlinked various bits and pieces which might provide some clarity as to the functions of some of the nodes used. Might be useful for anybody keen on understanding what the nodes functions are, however the UE4 documentation is a bit scarce and does not provide a great amount of clarity.

When time permits, i will be looking to extend this tutorial to include setting up a UMG progress bar to show our stamina on screen.

Hopefully my explanations are clear and easy to work through, however leave a reply if you there is anything that could have been improved on.

As a sort of TLDR, there is a link at below the tutorial to a BlueprintUE.com pastebin which will allow you to navigate your way around the blueprint via your browser.

Thanks folks


**Step 1.0 - **Set up the below variables in your ThirdPersonCharacter blueprint class and set our Max Walk Speed to 175 in the character movement component.

[table=“width: 450, class: grid, align: center”]

**Variable Name**
**Variable Type**
**Default Value/State**


**IsMoving?**
**Float**
0.0


**CanSprint?**
**Boolean**
False


**Stamina**
**Float**
100.0


**StaminaRegen**
**Float**
-0.5


**IsSprinting?**
**Boolean**
False


**StaminaDecay**
**Float**
0.2

Step 1.1 - To start things off, the first node we must add to our event graph is a ‘Set IsMoving?’ node which we will create by pulling a wire from our ‘Add Movement Input’ node (specifically the ‘Add Movement Input’ node which is wired from the ‘InputAxis MoveForward’ node). From here, we must then create a ‘Branch’ node which will be used to check if our IsMoving? variable is >0.1. Then from the true pin of the branch, we will insert a ‘Set CanSprint?’ node and set the CanSprint? variable to true. Similarly, from the false pin of the branch, we will insert a ‘Set CanSprint?’ node and set the CanSprint? variable to false.

http://i.imgur.com/1wDowle.jpg

Step 1.2 - Now coming back to the ‘Set IsMoving?’ node we created in 1.1, we will pull a wire from the float value input pin and create a ‘Dot Product’ node. Now we must insert a ‘Get Actor Forward Vector’ node and wire this in to our first pin of the dot product node. For our second pin, we can create a ‘Get Velocity’ node and from the return value create a ‘Normalize’ node which we will wire into our second pin of the dot product node.

http://i.imgur.com/xiW2jRg.jpg

Step 1.3 - From here we will now define what is to happen if the IsMoving? variable is not >0.1 by pulling a wire from the set CanSprint? node and creating a ‘Set Stamina’ node. Now we must drag in a reference to both our Stamina and Stamina Regen variables and subtract these. We can clamp our Stamina variable by using a ‘Clamp (float)’ node which restricts our Stamina from going above 100 and below 0.

http://i.imgur.com/nArO9lf.jpg

Step 1.4 - Now we must insert a ‘Branch’ node which will check if our Stamina is <30, then from the true pin of the branch we will insert a ‘Set CanSprint?’ node of which the state will be false. And from the false pin of the branch we will again insert a ‘Set CanSprint?’ node of which the state will be true.

http://i.imgur.com/KpM2PUJ.jpg

Step 1.5 - Create a ‘Branch’ node which will check if the IsSprinting variable is true or false.

http://i.imgur.com/X1rdODp.jpg

Step 1.6 - From the false pin on the branch node we created in 1.5, insert a ‘Set Stamina’ node. Now we can replicate the same set of nodes we made in 1.3.

http://i.imgur.com/yyHFuC9.jpg

Step 1.7 - From the true pin of the branch we created in 1.5, we will create another branch which will check if our Stamina is >=1.

http://i.imgur.com/VkmI0sa.jpg

Step 1.8 - From the true pin of the branch we created in 1.7, we will insert yet another branch to check if we are sprinting.

http://i.imgur.com/xl5FD4P.jpg

Step 1.9 - From the true pin of the branch created in 1.8 insert a similar set of nodes we input in 1.3 and 1.6, however now we want to minus the Stamina Decay from the Stamina.

http://i.imgur.com/2TWykb5.jpg

Step 1.10 - Moving back to the branch node we created in 1.7, we will pull a wire from the false pin and input a branch and we insert a ‘InRange (float)’ node which will we will use to check if our Stamina is in the range of 0.0 and 0.999999999999. From the true pin of the branch, we will insert a ‘Set IsSprinting?’ node with the state being false. We will identify where the ‘Set IsSprinting?’ node is connected to in 1.15.

http://i.imgur.com/4jtaHmO.jpg

Step 1.11 - We now must move back to the nodes we created in 1.4 and from the Set CanSprint? pin we will insert a branch which will check if the IsSprinting? variable is true or false.

http://i.imgur.com/QDdRMvD.jpg

Step 1.12 - From the false pin of the branch created in 1.11 replicate the same node set made in 1.3 and 1.6.

http://i.imgur.com/qo2t2Eq.jpg

Step 1.13 - From the rue pin of the branch created in 1.11 insert another branch which will check if the CanSprint? variable is true or false.

http://i.imgur.com/Dk8OIFn.jpg

Step 1.14 - From the true pin of the branch created in 1.13, replicate the same node set made in 1.9

http://i.imgur.com/NevNMLJ.jpg

Step 1.15 - Now we must amend our original sprint function created in the first tutorial. First we must insert a branch from the ‘InputAction Sprint’ Pressed pin which will identify if CanSprint? is true or false. From the true pin of this branch we will insert a ‘Set IsSprinting?’ node. Then from the ‘Set IsSprinting’ node, we will pull a wire and create a new timeline.
The timeline will have one float track named Sprint Increase. Set the track length to one second and create two keys on the track, the first at 0.0 seconds and the second at 1.0 seconds, now our Sprint Increase float track has a linear increase the duration of the track.

http://i.imgur.com/LNban1m.jpg

Now if we come out of the timeline editor window and from the ‘Set IsSprinting?’ node (true) we will wire this into the Play From Start pin of our timeline. Now from the released pin of the ‘InputAction Sprint’ node we will insert a ‘Set IsSprinting?’ node and set its state to false. From this node, wire this in to the reverse pin of our timeline.
Now drag a reference to our Character Movement component into the event graph from the components pane and from this node insert a ‘Set Max Walk Speed’ node, wiring in the update pin from our timeline to this node. Now wire our Sprint Increase float track from the timeline to our ‘Set Max Walk Speed’ node.
Finally, from the ‘Set IsSprinting?’ node created in 1.10, wire this node in to the reverse pin of the timeline.

http://i.imgur.com/WZu7Blk.jpg


Hopefully the tutorial helped, follow this BlueprintUE link to access the blueprint in your web browser.

Thanks again.

Really nice tutorial. Thanks!

One question about the IsMoving calculation.

Currently that resolves to a -1 or 1 telling you the movement is forward or backward.

What about side to side? I assume just use the right hand vector.

Also, if I am moving backwards the stamina calc is skipped, no? Or am I missing the logic there? as anything under 1 will be considered false?

Thank you, great to hear!

I am guessing you are implementing this tutorial in to a first person project, which is fine but we have to do additional checks to find our stafing vector. To achieve this, set up the below set of nodes before Step 1.1, also you will need to create a new float variable called IsStafing. This solution will now allow your sprint to be used when stafing side to side and also when moving backwards.

Any problems please let me know!

http://i.imgur.com/EvtHB9B.jpg

Hi Joviex, did that above solution solve your problem? I just want to ensure that this is resolved and then i will ammend my original post to include the solution.

Thanks.
Connor.

Hi connor, can you make a secon part to explain, how to put a bar for the stamina or, use the bp in other functions (like combat), this second is what im working on right now. Thanks, very helpfull.

Hi Neff10,

I will certainly try and put the second part together as soon as I can.
Regarding your request for other functions, what would you like to see regarding adding combat functionally? A health system can be easily implemented and we can also add some objects in the world that would damage our player when collided with, but further things we may have to first introduce an AI character.
Let me know what you would like to see, and I will see what can be delivered :slight_smile:

Thanks for the feedback!

Wow, that was quite informative. Very nicely done tutorial. :slight_smile: Personally, I would like to see the AI character be introduced.

Evening,

Hi Neff,
I have just completed the next tutorial for implementing the Stamina Progress Bar, I trust that this is suitable but please do get in touch if there is anything that needs further explanation or if you need assistance implementing Progress Bars into other situations.

Hi Yggdrasil,
Thanks for the kind words. Regarding a tutorial for implementing AI Characters, this can be done but I expect that this may take a bit longer to piece together in comparison to the two submitted thus far. I will certainly see what i can do on this front, as I really enjoy the process of putting these tutorials together. Yggdrasil, would you have any features that you may specifically want covered in a AI Character tutorial? I am quite happy to look into specifics if you require.

Thanks again.

The objects dealing damage to the character is a great idea, but i wld focus on the character component, functionts that affect on our stamina (combat as u said, climb, etc…), im not any expert but i think the combat can link with the objects, for example: object deals damage but you can block them if you have stamina, like the shield function of the combat. i cant explain better D:

Thanks a lot

How would I make a toggle sprint from this? Before I was using a flip flop to switch from play to reverse but after implementing this things got a bit weird. Sometimes the flip flop will go through and I’ll start sprinting but my stamina will stay the same unless I’m actually holding down the sprint button. I’ve tried a few things to get around it, but it seems the way it’s currently set up requires a button to be held for the stamina to decay.

What you could do is check if the player is moving on the ground, and if their velocity is greater than say 200 in order to drain stamina.

Also, as a formalism you shouldnt put any symbols such as a question mark (?) in variable names, especially a bool as it obviously only returns true or false. And same with your IsMoving? float variable, floats shouldn’t be named as if they were bools just for formalism sake.

Hi DestinyFaux,
Apologies for not responding sooner. Usually my phone would ping if I got a response on here, but have not set my new handset up to do this.
Let me have a play around with a few things today to get a toggle sprint working and I will get back to you.

I suppose this is just down to the preference of the programmer, this is really just a prompt for me as it reminds me at a glance that the variable reference is questionable.
The IsMoving? variable is named as such because I am questioning the value of the variable, that is the variables only purpose at this stage.
But yeah, all subject to opinion :slight_smile:

I understand what you mean, but that is the whole point of a bool variable, whether its active or not, yes or no, here or there, ect.

Awesome Tutorial. Learned a lot. But Im having a wierd problem. When I press shift after setting everything up, the character twitches and stops in his tracks. I’m trying to solve it but not much success.
I also did the widget tutorial to have a visual idea see if I got a clue and the bar appears empty but for a sliver of stamina that fades as soon as I press shift.

NEVER MIND, I AM A SIMPLETON!!!
Didn’t change the max value on the clamps to 100 so it maxed at 1 and made everything die of brain fart.
XD Thanks for the great tutorial.

Okay so found the bar problem, th Clamps didnt have the Max values set to 100.
However the character still gets stuck after pressing shift once.

Hey there Thanks for the awesome tutorial. I followed it to the letter, it works great except for one thing. Once the player stops sprinting, they can not move at all (sprint or walk) even if the stamina regenerates back to 100. Any solution would be fantastic.

Cheers.

I’m aware this is old but I hope you could read this/are still active -

I can not sprint, and when I hold shift I will walk at normal speed, when I let go, I can’t move at all.

I attempted to make the Stamina Bar to see if it’d work and I couldnt get the ‘Get Stamina’ to show up, and I did make the variables public.

Please reply!

Hey guys, I know this is a really old post and I don’t know if you managed to fix the error you was having but I think I may have found the problem you had.

When you created the timeline and the added the curves did you make sure you changed the value as well as the time?

The first point (set at 0.0) should have the same value as the walk speed and the second one (set at 1.0) should have the same value as your sprint speed.

Hope this helps you and anyone who comes across this same error later on.

how would you have stamina regen if you are only walking, not sprinting, and how would you do a delay after you stop sprinting so that you do not regen stamina instantly