Using and Creating Resources in Godot 4
Any game out there needs assets like textures, sounds, and music to provide a fun experience to its players. Godot treats these files as resources you can use throughout your project. Besides Godot’s built-in resources, you can also create your own to build powerful, modular systems. Custom resources make it easier to manage your project. […] By Eric Van de Kerckhove.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Using and Creating Resources in Godot 4
40 mins
- Getting Started
- Shop
- Player Item Display
- Shop Item Display
- What are Resources?
- Importing and Using Resources
- Applying a Sprite Texture
- Import Parameters
- External vs Built-in Resources
- Creating Custom Resources
- Your First Custom Resource
- An Inventory of Items
- Using Custom Resources
- The Shop Inventory
- Creating a Shop Display
- Showing the Shop Items
- Making Smart Resources
- Inventory Logic
- Player Script
- Displaying Player Items
- Saving and Loading Custom Resources
- Creating a Save Manager
- Connecting the Save and Load Buttons
- Where to Go From Here?
Making Smart Resources
Custom resources are more than data containers, you can add logic to them too!
At the moment, the items from the shop aren’t actually removed when you buy them. Their displays will simply disappear. In this next section, you’ll be adding logic to the inventory resource itself so it can move an item from its own inventory to another. To do this, you’ll need the following:
- A function to move an item in the Inventory resource
- A player script that has its own inventory
- Some way to show the player’s inventory
- Code to bring it all together in the shop script
Inventory Logic
First things first, add the following function to the inventory.gd script:
func move_item_to_inventory(item : Item, inventory_to_add_item_to : Inventory): # 1
for i in range(items.size()): # 2
if items[i] == item: # 3
inventory_to_add_item_to.items.append(item) # 4
items.remove_at(i) # 5
return # 6
The move_item_to_inventory
function will first find the index of the item in the inventory. If the item exists, it will add it to the other inventory and remove it from the original inventory. Here’s the code in more detail:
- The
move_item_to_inventory
function takes two parameters: the item to move and the inventory to add it to. - Loop through the items in the inventory
- If the item is found, perform the tasks listed below
- Add the item to the other inventory using the
append
function - Remove the item from the original inventory using the
remove_at
function - Quit out of the function
Don’t forget to save the script! With this function in place, it’s now easy to move an item from one inventory to another.
Player Script
For the next piece of the puzzle, create a new node as a child of the Shop node. Name this node Player, right-click it and select “Access as Unique Name” to make it easier to reference from scripts later on. Next, attach a new script to it and name the script player.gd. Make sure to create it inside the scripts folder.
The player node will hold the player’s inventory. Add the following code to the player.gd script, below the extends line:
class_name Player # 1
var player_inventory : Inventory = Inventory.new() # 2
Here’s a summary of the code:
- As always, use a class name.
- Declare a new inventory as
player_inventory
and store a new Inventory resource in it.
Nice! Save this player script and open the player_item_display scene.
Displaying Player Items
The player item display scene should show an item in the player’s inventory like the shop does.
At the moment, this scene doesn’t know what an item is or what to do with it. To fix that, add a new script to its root PlayerItemDisplay node and name it player_item_display.gd. Make sure to put the script in the scripts folder like before.
With the new script open, add the following below its extends
line:
class_name PlayerItemDisplay # 1
@onready var sprite_texture: TextureRect = %SpriteTexture # 2
func link_to_item(item : Item): # 3
sprite_texture.texture = item.sprite
The player’s item display is much simpler than the shop item display. It displays the item’s sprite, but not any of its other properties. Here’s what’s going on in the code:
- Class name for easy referencing
- Reference to the SpriteTexture node
-
link_to_item
takes an item as a parameter and sets the sprite texture to the item’s sprite
Almost there now. To finish up, save this script and open the shop.gd script. It needs some alterations to work with the player’s inventory and item displays.
To start with, add these variable declarations to the shop.gd script, below the cash_sound
variable:
@onready var player = %Player as Player # 1
@onready var player_item_display_h_box: HBoxContainer = %PlayerItemDisplayHBox # 2
@export var player_item_display_scene : PackedScene # 3
Here’s what they’re for:
-
player
is a reference to the Player node. This is needed to access the player’s inventory. -
player_item_display_h_box
is a reference to the HBoxContainer node. This is where you will put the player item displays. -
player_item_display_scene
stores a reference to the player_item_display scene.
Now these variables are in place, you can use them to show what items the player has. To do that, add this function to the shop.gd script:
func update_player_items_display():
for child in player_item_display_h_box.get_children(): # 1
child.queue_free()
for item in player.player_inventory.items: # 2
var new_item_display = player_item_display_scene.instantiate() as PlayerItemDisplay # 3
player_item_display_h_box.add_child(new_item_display) # 4
new_item_display.link_to_item(item) # 5
This function is almost identical to the update_shop_items_display
function. The only difference is that it shows the player’s inventory instead of the shop’s.
In more detail:
- Loop through the existing children of the HBoxContainer player_item_display_h_box and remove them
- Loop through the items in the player’s inventory, execute the code below for every item
- Instantiate a new player item display
- Add the display to the HBoxContainer
- Pass the item to the player item display to link it
With that, all that’s left is to move any item the player buys and reflect this change in the user interface. For that, you’ll need to add these two lines to the end of the _on_item_display_buy_pressed
function:
shop_inventory.move_item_to_inventory(item, player.player_inventory)
update_player_items_display()
This moves the item from the shop’s inventory to the player’s inventory and updates the player’s inventory display.
Save this script as well open the shop scene again. You’ll need to assign the Player Item Display Scene property so the shop script knows what scene to instantiate. Like before with the shop item display, drag the player_item_display scene from the scenes/shop_ui folder in the FileSystem dock onto the Player Item Display Scene property of the Shop node.
That was the final step! Run the project by pressing F5 and buy some monsters. You’ll see the player’s inventory update at the bottom of the window.
In the next section, you’ll learn how to save and load the state of the inventories.
Saving and Loading Custom Resources
You can save resources in Godot to disk and load them back again at a later time, both in the editor and in-game. Because of this, resources can be used to save and load the state of a game. This is useful to store data that you want to persist between play sessions.
For this project, you can save the inventory of both the shop and the player. You can then reload a saved game and restore the state of the inventories with a single button. Luckily, Godot makes this easy to do, all you need is a few lines of code!