FLOW CONTROL, FUNCTIONS AND CUSTOM EVENTS
So far what we've been doing has been relatively simple but as your code gets more complex you're going to need more ways to control what the Engine is doing. We've actually already used a few of the nodes covered here but I'll explain them again for the sake of completeness.
Firstly an aside on workflow and testing. Normally in a game you'll have some sort of input that triggers off the event or functionality you're working on. However for testing purposes that can be quite time consuming, so if you click on the Blueprints class defaults it's possible to get the Input to Auto Receive from Player 0 - this allows you to just use the keyboard key nodes in your blueprints and create very quick and hacky interfaces for testing - just remember to take them out again after you're finished!
Firstly make sure you're using a For Loop and not a For Each Loop - we'll get onto what they're used for later, when we cover Arrays. Basically a For Loop will run as many times as the difference between the First and Last Index. So if we put in values of 0 and 5 we'll get 6 loops.
You'll notice here we've subtracted 1 from our Number of Boxes so that if we put 5 in as our Number of Boxes Variables we get 0:4 which is 5 loops, you'll see why this is beneficial in a second. Each loop also includes the loop index number as the Index value - so the first loop is Index 0, second 1 etc. this allows us to do something incremental to our logic - in this case we're multiplying the Index by a Z Offset float (150 by default) which moves the boxes up: 0, 150, 300, 450 etc.
Note for the first box to not move we need the first index to be 0, hence why we do 0:4 instead of 1:5.
After the Loop has finished the Completed Execution pin will fire allowing the rest of your code to run.
Another one we've already used - the Branch node just takes a Boolean input and either does the True or False execution pin depending on the Value of the Bool.
(Often this would be called an If node, and actually, Unreal knows this and will select Branch for you if you type IF into the autocomplete search for nodes.)
The Delay node does what it says - waits as long as the input float and then carries on executing. The input value is in seconds of real time.
Note if you want to make a loop with a Delay you need to do something manually as is shown above. If you try and add a Delay to a For Loop each loop will execute in one frame, hit the Delay and then only one execution will happen once the Delay has expired. If you do make a loop with a Delay like this then make sure you have some logic that breaks the loop - or else it will run repeatedly, which isn't always advisable.
Lastly Delays and other latent nodes (nodes which depend on time, such as Timelines) can't be used inside of Functions - this is a design optimisation but can always be worked around using Custom Events in the Event Graph, just something to remember when you're designing your Blueprints.
We covered Switch on Int earlier - it chooses an output pin based on the Value of the Int. There are also Switches for hundreds of other Variable types but Int is probably the most common and useful.
Another node that does what it says - the DoOnce node will only fire the execution pin the first time it's triggered, ignoring all other inputs until it receives a Reset input. Here we're Printing the Index for our loops but we'll only Print the Once string once - try it out in level and see.
A very useful node for laying out your work and keeping things organised. The Sequence node just executes all the output pins in order, in the same frame. There's no functional difference between the two images above, except the first one is cleaner and easier to read. Once you start making very complex Blueprints you'll be glad of any ways you can keep thing clean.
The IsValid node isn't technically flow control but it works in the same way so we'll cover it here. What this does is checks if the Input Object is a Valid Object and Returns a True/False. What does an Object mean to be Valid? well it means that it is has the correct parameters assigned and isn't currently flagged to be deleted. If you've ever seen the "Accessed None" error in Blueprints then this is why - the Variable you're trying to get isn't currently assigned to anything, so the engine doesn't know what to do. Once we get on to creating and destroying components in a later tutorial we'll need some IsValid checks to make sure we're not getting these errors.
So before we talk about Custom Events, lets have a look at the Events that come ghosted (transparent) by default in the Event Graph:
BeginPlay - we've been using this already, basically this runs once when the game starts - great for setting up initial states and starting other things off.
ActorBeginOverlap - More game design than VFX but still useful - this triggers once when a physics object overlaps the collision of the Blueprint - we'll look at this in more detail but really useful for triggering off cinematic things like sparks when a player goes through a door etc.
Event Tick - This triggers every frame - WARNING: this can be very expensive. Generally most things don't need to update every frame, except animations. Note here I've used a Do N node to Print String only 10 times, so it doesn't spam the screen. Do N is the same as DoOnce but with N times instead of only 1.
Custom Event - now we're getting to the powerful stuff - we can create as many Custom Events as we need and call them from other parts of the Engine or Blueprint. Finally i'm just using a Enter key (with AutoInput set to Player 0), to trigger off this Custom Event.
Finally we get to Functions - these have a lot of similarities with Custom Events, in that they can be called from other parts of the Engine or Blueprint. Both Functions and Custom Events can also have an Input - here our Input is a Float value called Input. Because they're self contained bits of code Functions can also have Outputs - here we're just simply taking the Input value and multiplying by 2 then Returning the Result as our Output.
We also have a Function to Reset our Value to 1 and Keyboard Keys to trigger these off (remember the AutoActivate!).
This sort of setup is called Abstraction in coding - keeping each part of the code self contained and separated so that it's easier to work on and think about. Using lots of Custom Events and Functions will make your Blueprints easier to work with and understand and greatly help if you're working in a team environment and other people will need to edit your work.