In this tutorial, I'll show you how to use the Flow Graph System in Amazon Lumberyard. You will play with the visual scripting system to animate buttons and create interactions between the UI Canvas and your 3D scenes. Then, you will create another script to modify your 3D scene taking into consideration your avatar location. Finally, you'll be faced with a challenge.
Note that you are advised to read the rest of the series in order to fully understand the notations from this part.
Who Should Read This Tutorial Series?
This tutorial series is primarily aimed at two groups of game developers: those who are completely unfamiliar with game engines at all, and those who are familiar with other game engines (such as Unity, Unreal Engine, or Cry Engine), but not with Lumberyard. I assume that you have some knowledge of computer graphics notation, so I won't exhaustively cover all notations.
Flow Graph is a visual scripting system that allows you to implement complex game logic without the need to program a single line of code. All logic can be created, modified and removed with only a few UI interactions. Flow Graph is also useful for prototyping game-play scenarios, effects, and sounds.
At its core, Flow Graph consists of nodes and links. The former usually represent level entities or actions that may perform a specific action on a target entity. The latter are used to connect nodes and are represented as arrows that connect the inputs and outputs between nodes.
The Flow Graph can be opened in two main ways; the first is through the Main menu, using the link at View > Open View Pane > Flow Graph.
The second way is through the Flow Graph icon available in the Editor toolbar.
Open the Flow Graph using one of the available options.
The Flow Graph editor is composed of the following components:
- Node graph: main window grid for displaying flow graph nodes and connections.
- Components: browser tree pane for all nodes that you can use.
- Flow Graphs: browser tree pane for graphs and entities; every flow graph created will be placed here.
- Properties: pane for showing node input and output properties.
- Search: pane for searching graphs and nodes.
- SearchResults: pane for displaying search results.
- Breakpoints: pane for displaying breakpoints; an excellent way to debug your game or prototype.
Flow Graph Scripts
Before jumping right into the action, you need to learn the basics of Flow Graph scripts.
Flow Graph scripts are organized into four different categories and contained in the Flow Graphs (number 3 in the previous image) folder tree in the Flow Graph Editor.
- Level: This directory contains scripts that are specific to the level that is currently open. It contains Entities, Components, and Modules. Entities files are the flow graphs created and associated with an entity currently available in the level. Components are similar, but now the flow graphs are associated with components of the level. Modules represent a list of modules that are specific to the level.
- Global: Contains the UI Actions used to encapsulate UI logic for easy debugging and maintenance.
- Prefabs: Similar to the entity prefab, you can also create graph prefabs. You can create an event inside a prefab, give it a name, and then reference the prefab instance as you normally do for an entity.
- External Files: Represent a list of imported or created Flow Graph scripts.
Flow Graph Scripting: UI Canvas as the Default View
In the previous tutorial, you created a UI Canvas containing some buttons. You may also remember that it was not fully tested. It is now time to go back and finalize it.
The main idea behind the UI Canvas is the following:
- When you run your game (Control-G), the UI Canvas should be loaded (instead of the first level).
- When you click the Start Game button, two sequential actions occur:
- 1) The UI Canvas fades away.
- 2) You load your CompleteFirstLevel.
Open Lumberyard Editor and then the UI Editor. Click Open and open your MyCanvases.uicanvas.
Under the Hierarchy pane, select the Background element. Now, under the Properties pane, click Add Component... and then select the Fader component.
Below the Image properties; a new property called Fader will be displayed.
This Fader property will be used to fade out the UI Canvas when you load your level.
Flow Graph Scripting
Start by opening the CompleteFirstLevel and then open the Flow Graph Editor. An empty Flow Graph should appear.
Under the Components pane, select the graph Start, under the Game category.
Note that you can also use the Search Keyword to search specific nodes (when you know what to search).
Now, click on File > New to create a new node graph. The default name is Default, and it's placed under the External files section in the Graphs pane.
Now, drag the Start node into the node graph (center of the screen).
The Start node is the default node that is executed when you launch your game using the Switch to Game option. Therefore, normally most of the node graphs will start at this node.
Before adding the necessary nodes to display your UI Canvas, you need to learn additional information regarding the node graph and its nodes properties.
Flow Graph Nodes Description
A node is represented in Flow Graph as a box with inputs and outputs.
A node consists of input ports on the left side for receiving information and output ports on the right side for transmitting information. Output ports are activated depending on the function of the node. Ports can have the following different data types.
|Any||Green||Unspecified, any data type can be received|
|Boolean||Blue||True or False|
|EntityID||Green/Red||A unique value that identifies any entity in a level|
|Float||White||A 32-bit floating point value|
|Int||Red||A 32-bit positive or negative number|
|UInt64||n/a||A 64-bit positive or negative number|
|String||Turquoise||An array of characters used for storing text|
|Vec3||Yellow||A 3D vector consisting of three floating-point values. Can be used to store positions, angles, or color values|
|Void||n/a||Used for ports that do not accept any value but are instead triggered to pass the flow of control through a flow graph|
Taking into consideration the previous image:
- The text with blue background represents the node name.
- The text with red background represents the target entity.
- The arrows on the left part of the node represent the input ports of the MoveEntityTo node.
- The arrows on the right part of the node represent the output ports of the MoveEntityTo node.
To consult a complete documentation regarding the Flow Graph nodes, you should read the official documentation.
Flow Graph Scripting: Finishing the UI Canvas
When the game starts, you want to load your UI canvas. Fortunately, Lumberyard has a node for that. Select the Load node under UI > Canvas and drag it into the node graph.
This node has two main properties:
- Activate: it is automatically triggered when this node is called.
- CanvasPathname: represents the path name to your UI Canvas. Here you should put the name of the UI Canvas created in the previous tutorial (MyCanvases.uicanvas).
Select the Load node and under the Properties pane, change the CanvasPathname property to MyCanvases.uicanvas.
When you press Enter key, the property CanvasPathname inside the Load node should change accordingly.
This Load node is almost complete. Your next step is to connect the Start node into the Load node. This is performed by dragging a link (or arrow) from the Start output into the Load Activate input.
If you make a mistake when connecting an arrow, you can easily fix that. You must use the right mouse button to click on the arrow and Remove it. Note that you can also choose other options like Disable, Delay, or Any. I won't explain them in this tutorial since they're not important for what we want to accomplish.
Since we want to use a button to trigger one action, we need to add one ActionListener node. Under the UI > Canvas, drag the ActionListener into the node graph.
The ActionListener has three very important properties:
- CanvasID: Represents a unique integer identifier of the canvas to listen to. In other words, it relates to the canvas that is loaded in the previous node. Therefore, it must have the same identifier as the MyCanvases.uicanvas.
- ActionName: Represents the name of the action that the ActionListener will listen. This action name is passed when the user clicks a button.
- OnAction: It triggers the correct output when the canvas sends the action; it sends an order to be performed.
I'm not covering the Activate again since I explained it earlier.
The first step is to connect the OnLoad to the ActionListener Activate. Then, to pass the canvas id, you must connect both CanvasID output and input. Note that when you connect them the CanvasID = 0 changes to CanvasID.
The ActionName is not as simple since we must first define an action for our button. The idea is to add one Action click to the Start Game button.
Open the UI Editor, and open the MyCanvases.uicanvas. Select the Start Game button, and under the Properties pane, add the string NewGameClick to the Click Action.
Save the MyCanvases.uicanvas and go back into the Flow Graph editor. Select the ActionListener node and change the ActionName property to NewGameClick.
The ActionListener is now configured. What remains now is to configure the action performed when this ActionListener is triggered. Recall the Fader component added earlier. It is now time to use it.
For that, you need to add the Animation node inside the UI > Fader tree into the graph node.
The new properties to look at are:
- ElementID: Represents the unique integer identifier of the Fader element.
- StartValue: Represents the value for the Fader to start; it ranges from 0 to 1.
- TargetValue: Represents the value for the Fader to end; again, it ranges from 0 to 1.
- Speed: Represents the seconds taken by the Fader to fade; 1 represents 1 second, 2 would be twice as fast. 0 represents an instant action.
- OnComplete: Triggers the output when the Fader is complete.
The first step is to verify the ElementID from the Fader component. For that, open the UI Editor, load your canvas, and select the Background component. Inside the Properties pane, take a look at the number inside the Id element.
Note that you selected the Background element, since it is the one that has the Fader component. Close the UI Editor and change the ElementID of the Animation node to 2.
Next, change the StartValue to 1 and the TargetValue to 0. Leave the Speed value as default.
Now, connect the OnAction (ActionListener) to the Activate input (Animation). Once again, connect the CanvasID together (Load node to the Animation node).
This Flow Graph is almost complete. To understand what is missing, play the game (Control-G). What do you see? Your menu with the correct action inside the Start Game button, but no mouse cursor to assist you. Let's fix that, then.
Look for the MouseCursor node inside the Input tree and add it to the graph node. This node only has two inputs (Show and Hide). Both are self-explanatory, right?
Connect the Start output (Start node) into the Show input (MouseCursor node). Then, connect the OnAction output to the Hide input.
You can now run the game and test if everything is OK. You will realize that it is.
However, we will perform one additional performance step. Since we don't want to create games with memory leaks, we should get into the habit of doing things correctly. After the fade animation ends, we should unload the canvas.
Add the Unload node (UI > Canvas) as your final node into the node graph. Connect the OnComplete (Animation) output into the Activate node (Unload). Finally, connect the CanvasID together (Load node to the Unload node).
The complete flow graph is:
Save your flow graph and name it mygraphdemo.
More Flow Graph Scripting
The next step of this tutorial is to create another flow graph. However, this time, you will directly interact with the objects within your 3D scene to construct the graph. The main idea is to use the player location to interact with a proximity trigger to switch on a lamp.
In the RollupBar, select Entity > Triggers and drag a Proximity Trigger into the 3D scene.
Place the Proximity Trigger near a lamp. The yellow 3d box represents the trigger area.
Right click the Proximity Trigger and select the Create Flow Graph option.
Name it TriggerGraph and click OK. The Flow Graph editor should open. You will notice that this time the graph will be placed inside the Level > Entities section.
Now, rearrange your interface in order to see the Proximity Trigger, the lamp (Light1) and the Flow Graph Editor at the same time.
Select the Proximity Trigger and, inside the graph node, use your right mouse button and select the Add Selected Entity option.
A new ProximityTrigger node will appear.
The only properties that we will use will be the Enter and Leave outputs. The first is triggered when the player enters the Proximity Trigger area, while the second is triggered when the player leaves the Proximity Trigger area.
Next, select your Light1 element and deselect the Active option inside the Entity Properties pane.
With the Light1 selected, inside the Flow Graph use the right mouse button and select Add Selected Entity again.
Now you must connect the ProximityTrigger node with the Light node. Connect the Enter output into the Enable input. Finally, connect the Leave output into the Disable input.
Save the flow graph and name it TriggerGraph. It is now time to run the game and validate your new flow graph. Everything should work as expected.
In order to test the knowledge you've acquired so far, you are now challenged to recreate the default Lumberyard getting-started-completed-level. For that, you will need to play with the brushes, lighting, materials, textures, terrains, and flow graphs. In short, apply everything that you've learned so far. Your final level should look like the following:
This concludes this tutorial on Lumberyard. In this tutorial, I've shown you how to use the Flow Graph System. You have played with the visual scripting system to set up the UI Canvas as your default view, and have created interactions between the UI Canvas and your 3D scenes. Then, you created a script to modify your 3D scene, taking into consideration your player location and a proximity trigger. If you have any questions or comments, as always, feel free to drop a line in the comments.