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.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 5 of this article. Click here to view the first page.

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:

  1. The move_item_to_inventory function takes two parameters: the item to move and the inventory to add it to.
  2. Loop through the items in the inventory
  3. If the item is found, perform the tasks listed below
  4. Add the item to the other inventory using the append function
  5. Remove the item from the original inventory using the remove_at function
  6. 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.

Player node

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:

  1. As always, use a class name.
  2. 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.

Player inventory example

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.

Player item display script

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:

  1. Class name for easy referencing
  2. Reference to the SpriteTexture node
  3. 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:

  1. player is a reference to the Player node. This is needed to access the player’s inventory.
  2. player_item_display_h_box is a reference to the HBoxContainer node. This is where you will put the player item displays.
  3. 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:

  1. Loop through the existing children of the HBoxContainer player_item_display_h_box and remove them
  2. Loop through the items in the player’s inventory, execute the code below for every item
  3. Instantiate a new player item display
  4. Add the display to the HBoxContainer
  5. 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.

Drag player item display

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.

Buy all monsters

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!

Contributors

Over 300 content creators. Join our team.