Timelines and Triggers
So today we're going to be looking at some more advanced ways of interacting with our Blueprints and getting our Blueprints to control our Materials, Particles and Meshes.
Here I've created a Timeline with 4 Tracks - one of each type. A Float, Vector, Colour and Event Track. These work like any animation editor with Keyframed Values, which allow us to control anything we need to, over the time of the Timeline. Note the two options checked at the top for AutoPlay and Loop - these are reflected on the Timeline node by the little Play symbol and Looping arrows respectively.
Float tracks are useful for single data items, such as the Roughness of a Material or the Intensity of a Light, Vector tracks for Position or Rotation data, Colour for Material or Light Colours and Events for triggering off other parts of your code. Note the Value of the Event track doesn't matter - just the Time of the Keyframe.
Also note, similar to a For Loop, we have a Finished Pin to trigger off the rest of the code after the Timeline has finished.
Often with a looping Timeline you're going to want to randomise the start time to ensure that the Actors aren't all in sync in the level - imagine a level with 4-5 rotating ceiling fans, it's going to look wrong if they're all rotating exactly the same. Luckily there's an easy way to do this - instead of using Autoplay we generate a random Float first and then set this to the New Time, using the Set New Time node - simple!
Just having access to Timelines is incredibly powerful, but we can also use them in smart ways to make things even more powerful and easier to iterate and work with. Here I've created a Master Timeline that triggers off two other Timelines and then a third Timeline on the Finished Pin of the second one. This approach makes it much easier to see what each of the Timelines is doing and adjust Parameters and Timing to iterate on your effect better. Note there's going to be a small additional cost to having multiple timelines running simultaneously so this may not be the most optimal solution but it's definitely easier to work with.
Similarly, instead of using a Vector Track, I've used a Float track as the input of a Lerp between two Vectors - this separates the animation curve from the values and makes it easier to see what's happening and easier to control. Another benefit of this workflow is that you can use the same lerp to control 2 or more things at once, eg Rotation, Colour and Emissive intensity with a single animation timeline and 3 lerps.
If you add a Box Collision component and look to the bottom of the Details panel you see a lot of options for Events - OnClicked, OnOverlap, OnActivated, etc. These are all Events that the Engine can process when the condition is met, ie the object is clicked on, overlapped by another Physics object or Activated by code. Lets create an OnComponentBeginOverlap.
Now we have an event that will fire when our Camera starts to Overlap the Box Collision - here I've just set up the Blueprint to turn on a light when this happens but this can be used for anything - a door slamming shut behind a player, a proximity light for a residential house, etc. etc.
This Collision Box Overlap technique is also the way switches are made in games: OnBeginOverlap: allow the player input and put the "Press E" prompt on screen, if the Player presses E: do something, OnEndOverlap remove the prompt and turn off the player input.
So far everything we've been doing has been relatively simple, but games aren't simple things so we need to have some way to increase the complexity of what we're doing - enter Boolean Logic. I won't go into too much detail here (Google it if you need more detail) but the important thing to notice here is the AND node - this is only going to Return True if both Box1Hit and Box2Hit are True - we've started making the basis of a game!
AND, OR, EQUALS, NAND, XOR, NOTEQUALS etc. are all available and can be combined to create any sort of logical check you need.
Notice here also the use of a Custom Event - both Overlaps want to do a check for if they've both been hit, by having it as a Custom Event (or Function) I only have to write that code once, which makes things quicker, easier to maintain, and less prone to errors.
Finally I just want to touch on the Level Blueprint. Everything we've discussed so far has been in relation to an Actor Blueprint, but it all applies just as well to the Level Blueprint too - this is a set of nodes that are associated with the Level, usually a good place to put your player progression and game mechanics but also somewhere a VFX artist might put things. With an object selected in world you can right-click and get access to its events and functions or add a reference to it, so that you can work with it in your code.