Saltar al contenido
ReadySpawn

Cómo hacer un sistema de inventario en primera persona en Unity

Por Imersa Studios · Actualizado el

Lanza un raycast desde la cámara para encontrar un objeto, recógelo al pulsar una tecla guardándolo en una lista y emparentándolo a la mano del jugador, cambia el objeto en mano con la rueda del ratón y suéltalo desemparentándolo y reactivando su Rigidbody.

1. Marca lo que se puede recoger

Da a cada objeto recogible un pequeño componente con su nombre e icono. El inventario busca ese componente en lugar de etiquetas, así que los diseñadores no pueden olvidar una etiqueta.

using UnityEngine;

[RequireComponent(typeof(Rigidbody))]
public class InventoryItem : MonoBehaviour
{
    public string displayName = "Item";
    public Sprite icon;
}

2. Mirar, aviso, recoger

Lanza un rayo corto desde la cámara en cada frame. Si alcanza un objeto, muestra su nombre; si el jugador pulsa E, guárdalo.

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Inventory : MonoBehaviour
{
    public Transform cam, hand;
    public float reach = 2.5f;
    readonly List<InventoryItem> items = new();
    int selected;

    void Update()
    {
        var kb = Keyboard.current;
        if (Physics.Raycast(cam.position, cam.forward, out var hit, reach)
            && hit.collider.TryGetComponent(out InventoryItem item)
            && kb.eKey.wasPressedThisFrame)
            PickUp(item);

        float scroll = Mouse.current.scroll.ReadValue().y;
        if (scroll != 0 && items.Count > 0)
            Select((selected + (scroll > 0 ? 1 : -1) + items.Count) % items.Count);

        if (kb.gKey.wasPressedThisFrame && items.Count > 0) Drop();
    }

    void PickUp(InventoryItem item)
    {
        item.GetComponent<Rigidbody>().isKinematic = true;
        item.GetComponent<Collider>().enabled = false;
        item.transform.SetParent(hand, false);
        items.Add(item);
        Select(items.Count - 1);
    }

    void Select(int index)
    {
        selected = index;
        for (int i = 0; i < items.Count; i++)
            items[i].gameObject.SetActive(i == selected);
    }

    void Drop()
    {
        var item = items[selected];
        items.RemoveAt(selected);
        item.transform.SetParent(null, true);
        item.GetComponent<Collider>().enabled = true;
        var rb = item.GetComponent<Rigidbody>();
        rb.isKinematic = false;
        rb.AddForce(cam.forward * 3f, ForceMode.VelocityChange);
        if (items.Count > 0) Select(Mathf.Clamp(selected, 0, items.Count - 1));
    }
}

3. Añade la interfaz de la hotbar

Una hotbar es una fila de casillas: una Image por casilla que muestra items[i].icon y un resaltado en selected. Reconstrúyela cuando cambie la lista, no en cada frame. Lanza un evento C# (public event System.Action Changed;) desde PickUp, Select y Drop y deja que la interfaz lo escuche.

¿Construirlo o comprarlo?

Construir con esta guíaSistema de Inventario (nivel de $7.99)
Aviso de recogida con nombre del objetoLo añades túIncluido
Hotbar con iconos y resaltadoLo añades túIncluido
Teclas numéricas 1-9 y rueda del ratónSolo la ruedaAmbos
8 objetos de ejemplo con iconos, escena de demostraciónNoIncluido
Tiempo hasta lo primero jugableUna o dos tardesMinutos

Si quieres aprender, constrúyelo. Si quieres pasar a tu juego de verdad, el Sistema de Inventario trae esto con todo el código fuente, para que aún puedas cambiarlo todo. Suma el Sistema de Guardado y Carga para conservar los objetos entre sesiones y el Sistema de Puertas para llaves que abren puertas cerradas.

Preguntas frecuentes

Quién lo escribió

Imersa Studios crea los sistemas Unity, los packs low poly y las guías que se venden en itch.io. El código y las técnicas de aquí salen de publicar esos productos. Más sobre el estudio.