Ir para o conteúdo
ReadySpawn

Como fazer um sistema de inventário em primeira pessoa no Godot 4

Por Imersa Studios · Atualizado em

Descreva os itens como Resource, guarde os slots num autoload para que todas as cenas acessem, colete itens com um RayCast3D na câmera e troque o slot selecionado com a roda do mouse. Salve os ids dos itens em JSON.

1. Itens como resources

Um Resource é o jeito do Godot de descrever dados que você edita no Inspector. Um arquivo .tres por item tira nomes e ícones do código:

class_name Item
extends Resource

@export var id := ""
@export var display_name := ""
@export var icon: Texture2D

2. Um autoload que guarda os slots

Adicione este script em Project Settings > Globals > Autoload como Inventory. Um sinal avisa a interface para redesenhar:

extends Node

signal changed
const SIZE := 9
var slots: Array[Item] = []
var selected := 0

func _ready() -> void:
    slots.resize(SIZE)

func add(item: Item) -> bool:
    for i in SIZE:
        if slots[i] == null:
            slots[i] = item
            changed.emit()
            return true
    return false

func drop_selected() -> Item:
    var item := slots[selected]
    slots[selected] = null
    changed.emit()
    return item

3. Pegue o que você está olhando

Coloque um RayCast3D na câmera, com uns 2 m de alcance. Quando o jogador aperta a ação de interagir e o raio acerta um item, adicione o item e apague o nó:

@onready var ray: RayCast3D = $Camera3D/RayCast3D

func _unhandled_input(event: InputEvent) -> void:
    if event.is_action_pressed("interact") and ray.is_colliding():
        var target := ray.get_collider()
        if target is Pickup and Inventory.add(target.item):
            target.queue_free()
    if event is InputEventMouseButton and event.pressed:
        if event.button_index == MOUSE_BUTTON_WHEEL_UP:
            Inventory.selected = posmod(Inventory.selected - 1, Inventory.SIZE)
        elif event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
            Inventory.selected = posmod(Inventory.selected + 1, Inventory.SIZE)
        Inventory.changed.emit()

Pickup é um script pequeno num StaticBody3D ou RigidBody3D com um item: Item exportado. Para a hotbar, um HBoxContainer de TextureRects que redesenha no Inventory.changed é suficiente.

4. Salve o inventário

Salve os ids dos itens, não os resources, para que o save continue funcionando quando você trocar um ícone:

func save_inventory() -> void:
    var ids := Inventory.slots.map(func(i): return i.id if i else "")
    var file := FileAccess.open("user://inventory.json", FileAccess.WRITE)
    file.store_string(JSON.stringify(ids))

Ao carregar, leia os ids e mapeie cada um de volta ao seu .tres com um dicionário de itens. O mesmo padrão salva portas, moedas e checkpoints.

5. Ou comece com sistemas prontos

A coleção 10 Game Systems para Godot 4 traz este inventário junto com salvar e carregar, portas com chave e teclado numérico, loja, RPG inicial e mais cinco, cada um com cena de demonstração e GDScript tipado. O Door System é grátis.

Perguntas frequentes

Quem escreveu

Imersa Studios cria os sistemas Unity, packs low poly e guias vendidos no itch.io. O código e as técnicas daqui vêm de lançar esses produtos. Saiba mais sobre o estúdio.