Previous chapters typically focused on specific groups of features within Godot, such as 2D and 3D worlds. This chapter, by contrast, focuses on how to achieve common tasks within Godot. The Unity documentation on such tasks is extensive. But the Godot documentation is limited. So let’s now take a look at some common tasks.
How to Make Objects Look at the Cursor
You’ll often want objects – like the player or enemy characters – to face the mouse cursor as it moves around the screen. Twin-stick shooter games are a common example. In these games, the player normally controls character movement – up, down, left, and right – using keyboard arrow keys or gamepad presses; and they control player orientation through mouse movement, specifically the player look direction. See Figure 7-1.
In short, we want to adjust an object’s rotation to face the mouse cursor. Listing 7-1 demonstrates how a 2D Node can be rotated to face the cursor at any time.
Listing 7-1 should be attached to any sprite node, and it’ll make the node point toward the cursor. This code assumes that an object, by default, is rightward facing. That is, its resting pose will see the character looking toward the right, along the X axis. See Figure 7-2. If that’s not the case for your object, then simply use the RotationDegrees field from the inspector to rotate the node so that it’s rightward facing. The _Process event happens on each frame, and it will call GetLocalMousePosition to retrieve the mouse cursor location on screen, relative to the calling node.
Singletons and Auto-Loading
Sometimes you’ll need – and depend upon – behaviors that should exist in every scene. This may include player scores, player inventory, health statistics, and other kinds of global data or functionality that needs to be available almost everywhere. Now, when you’re creating objects in different scenes – such as a player scene, or an NPC scene, or an environment scene – it can be tricky to properly test these scenes in isolation from each other without the needed global functionality being present. In our use case here, we’ll write some code that simply prints the names of nodes as they’re added to the scene for any scene anywhere. If the added node belongs to a specific group, such as “Lava Pit,” then we’ll connect up its OnEntered signal to a function so we can receive notifications about when the player enters the lava pit, presumably to take damage or be destroyed. Now, this behavior needs to exist in every scene and to be present before any gameplay nodes are added to the scene, so we can be sure of catching every subsequently added node that could be a lava pit. We can achieve this behavior using Singletons configured to Auto-Load. Singletons are simply globally accessible classes, of which there can be only one instance simultaneously. The Auto-Load feature of Godot ensures your Singleton classes are added automatically to each and every scene at runtime, and further that’ll be added before other scene nodes. Let’s start by creating a new empty scene with a single Node2D object. See Figure 7-3.
Next, let’s add the following script, as shown in Listing 7-2, and then attach it to the root node of the scene. This code prints the name of each newly added node and also connects its signal to an event handler if the node belongs to the lava pit group.
//Check group membership, and add to lava pit handler if needed
N.Connect("OnLavaEntered", this, "OnLavaEnter");
private void OnLavaEnter()
//Do damage stuff here
Print the Name of Newly Added Nodes
Now save the scene and access the Project Settings. Choose Project ➤ Settings from the Application Menu, and access the AutoLoad tab. From there, search for and find your SingletonScene, and click the Add button to add it to the AutoLoad list. See Figure 7-4.
Great! Now your Singleton scene will automatically be added to any and every scene at runtime prior to any other nodes. This means our code will successfully detect the addition of new nodes, including nodes created at scene startup, because they are added after the creation of our Singleton.
Often, you’ll be working with scenes that contain many nodes. Some of these nodes will be manually created and named. But some will be imported from mesh files or auto-generated by add-ons, and these nodes feature default naming. In these instances, you could have a ton of nodes to rename if you want a nice, neat naming convention applied to all nodes in the scene tree. Additionally, you may need to refer to nodes by name using the GetNode or FindNode functions, and you’ll probably want memorable, meaningful, and structured names for your nodes. You can rename nodes individually by right-clicking a node and choosing Rename from the context menu. However, Godot also features a Batch Rename tool for renaming multiple nodes in one operation. To access this, select multiple nodes in the scene tree, and right-click. The context menu should display a Batch Rename option. If it doesn’t, you can also access the Batch Rename tool by pressing Ctrl+F2 on a PC or Cmd+F2 on a Mac. See Figure 7-5.
After accessing the Batch Rename tool, you’ll be presented with an options menu. This allows you to specify object names, and naming patterns, to search for in the selection and then rename based on specific criteria. See Figure 7-6. In this example, the aim is to rename all objects consistently and to append sequential numbering.
When you’re ready to apply Batch Rename to the selected objects, just click the Rename button. When completed in this example, the renamed objects are as shown in Figure 7-7.
Textures As Masks
Consider Figure 7-8. This shows two separate image files. One is a brick texture, and the other is a simple black and white outline. Sometimes, you’ll have two separate textures like this in Godot, and you’ll want to use the shape image as a frame or space inside which the other image should display. The outline or shape image is known as the Mask – or sometimes the Stencil.
Let’s see how we can create a dynamic mask inside Godot – a mask that can be moved, changed, or updated over time, if we need it to. Start by importing two images into Godot; for our example here, I’ll use the brick image and the black and white outline. See Figure 7-9. Then create a new scene and add the brick image as a Sprite texture.
Next, add a 2D light node to the scene. Right-click the root and choose Add Node, and then select Light2D. See Figure 7-10. The act will act like a projector for the mask.
After adding the Light2D node, load your mask texture into the Texture slot from the Inspector, and then position the light over the brick texture. You’ll notice that, by default, the light brightens the texture behind. See Figure 7-11.
Now select the brick texture in the background, and then add a new CanvasItemMaterial from the Material slot in the Inspector. This material will control how the texture should interact with intersecting light. See Figure 7-12.
After creating the CanvasItemMaterial, change the Light Mode to Light Only. When you do this, the texture changes showing only the areas within the light texture and effectively creating a mask. However, the pixels still seem slightly washed out. We’ll fix this in the next step. See Figure 7-13.
We can eliminate the washed out look by selecting the Light2D node and by changing its Mode to Mix. Now, the pixel saturation will be restored, and the texture behind will continue to be masked even after you move the Light around! Great. You’ve just created an effective 2D Mask. See Figure 7-14.
Type-Independent Function Calling
As you develop real-world games with Godot, you’ll make lots of classes and functions and properties. As your projects develop in complexity, you’ll need to call different functions on different classes, but it can sometimes be difficult or messy to ascertain a Node’s type in advance. That’s where Godot’s HasMethod and Call functions are useful. These functions are part of the ultimate ancestor Object class and so are supported by every object. This means you can try to call a function of a specified name on any object using the following code in Listing 7-3.
Calling a Named Function
Progress Bars and Loading
Large scenes with many assets – such as an RPG town or a village – can take quite a while to load fully. Having your game suspend or hang for long periods is a frustrating experience. Consequently, it makes sense to load larger scenes in a separate thread, or process, to avoid stalling the game entirely. And you may show a progress bar or loading screen to express the loading progress. You can achieve that in Godot easily using the TextureProgress node and a simple script. Simply create a new 2D scene and create a TextureProgressnode. See Figure 7-15.
Next, attach the following script, as shown in Listing 7-4, to the TextureProgress node. This script will load the specified scene and update its progress in the bar.
public class TextureProgressMain : TextureProgress
CallDeferred("ThreadDone", RIL.GetResource() as PackedScene);
if(StageCount >= RIL.GetStageCount())
//Poll current stats
Error PollData = RIL.Poll();
if(PollData == Error.FileEof)
StageCount = RIL.GetStageCount();
if(PollData != Error.Ok)
private void ThreadDone(PackedScene R)
SceneTree ST = GetTree();
Node Root = R.Instance();
ST.CurrentScene = null;
ST.CurrentScene = Root;
public override void _Ready()
TimeStart = OS.GetTicksMsec();
ThisThread = new Thread();
ThisThread.Start(this, "ThreadLoad", ScenePath);
When this script is attached to the TextureProgress node, several parameters are exposed from the Inspector, as shown in Figure 7-16.
This script accepts two parameters. The first is Scene Path, which is the resource path to the scene, which should be loaded. The second is Minimum Time. This specifies a minimum amount of time, in seconds, for which the loading bar will show. In cases where a scene loads incredibly fast, this will prevent the loading screen from simply flickering into view briefly and then disappearing. The progress bar will represent either the loading progress of the scene or the progress of the minimum time, whichever is the slowest.
How to Save Game States
Save states let gamers retain their progress, resuming from earlier sessions. With save states, your game remembers how much progress you’ve made. There are many different ways to code save states, and this section looks at JSON – a text-based language for saving game data easily and quickly. Let’s start by considering the following sample scene, shown in Figure 7-17 and included in the book companion files.
The sample scene features three zombie characters. We’ll save their position and color, allowing it to be restored in later play sessions. You can, of course, save any data you want. To get started, we’ll need to create two script files: one to be attached to each object that can be saved and the other which is a global script that manages the save and load process. First, select all objects to be saved – the zombies in our example – and add them to the same group. Here, I’ve created a group called Persistent. See Figure 7-18.
Next, the following script should be attached to each sprite to be saved. This script file is intended to be called, or invoked, by the Save Game Manager. It serves only two purposes. First, it converts its properties – like position and color – into a JSON string for Save operations. And second, it converts a JSON string back into properties for Load operations. These two critical processes effectively convert an object to and from JSON. See Listing 7-5.
public class SerializeNode : Sprite
public Godot.Collections.Dictionary<string, object> Save()
return new Godot.Collections.Dictionary<string, object>()
public void Load(Godot.Collections.Dictionary<string, object> SavedData)
Position = new Vector2((float)SavedData["PositionX"],(float)SavedData["PositionY"]);
Modulate = new Color((string)SavedData["ModColor"]);
Serializing a Sprite Object
Next, create a Node2D object, and attach a new script (SaveState), which can be used to invoke saving and loading behavior for each object. See Listing 7-6.