Consumable Items

Consumable items are removed after usage. They are consumed from a user's backpack, and typically grant special effects to the player. Some examples of consumable items:

  • Food or drink item that heals the player
  • A potion that grants temporary invincibility
  • A ticket that can be shredded to grant access to an exclusive area within the space
  • A speed potion that increases the player's speed by 50% and jump height by 20% for 10 seconds

Creating a Consumable Item

To create a consumable item, you need to create a basic item and enable the Consumable toggle in the item settings. See Creating and Managing Items for a guide on creating items.

Navigate to the settings of your item and scroll down until you see a toggle for Consumable under the backpack settings. Enable this toggle to give some basic functionality to consume the item and reveal additional settings.

Enable consumable toggle to make an item consumable

  • Duration: How long the item will be active after consuming. You can set this to 0 seconds if you wish to apply an effect immediately instead of over a duration.
  • Cooldown: How long after the duration expires before it can be consumed again. 0 seconds is a valid value, which will disable the cooldown.

For example: setting duration to 10 seconds and cooldown to 5 seconds means that the item can be consumed every 15 seconds.

Important

The duration and cooldown timers will continue to run even when outside of the space or when the item is deleted from and/or re-added to the backpack. These timers are also based on real-world time, so it will be the same regardless of time scale.

Consumables with Scripting

In order to make the consumable actually do something, behavior will need to be defined within a Script Machine and Scripting Graph inside of a Space package’s scene, or in a C# script.

C# Scripting

Here's an example of implementing a consumable item in C#:

using SpatialSys.UnitySDK;
using UnityEngine;

/// <summary>
/// Attach this script to an object in the space's scene.
/// </summary>
public class ConsumablesManager : MonoBehaviour
{
private GameObject nightVision;

private void Awake()
{
SpatialBridge.inventoryService.onItemConsumed += OnItemConsumed;
}

private void OnDestroy()
{
SpatialBridge.inventoryService.onItemConsumed -= OnItemConsumed;
}

private void Update()
{
nightVision.SetActive(
SpatialBridge.inventoryService.items.TryGetValue("Nocturnal pill item ID from Studio", out IInventoryItem nocturnalPill) &&
nocturnalPill.isConsumeActive
);
}

private void OnItemConsumed(string itemID)
{
if (itemID == "Pizza item ID from Studio")
{
// Eating the pizza makes you jump!
if (SpatialBridge.actorService.localActor.avatar != null)
{
SpatialBridge.actorService.localActor.avatar.Jump();
SpatialBridge.actorService.localActor.avatar.AddForce(new Vector3(5f, 15f, 0f));
}
}
}
}
using SpatialSys.UnitySDK;
using UnityEngine;

/// <summary>
/// Attach this script to an object in the space's scene.
/// </summary>
public class ConsumablesManager : MonoBehaviour
{
private GameObject nightVision;

private void Awake()
{
SpatialBridge.inventoryService.onItemConsumed += OnItemConsumed;
}

private void OnDestroy()
{
SpatialBridge.inventoryService.onItemConsumed -= OnItemConsumed;
}

private void Update()
{
nightVision.SetActive(
SpatialBridge.inventoryService.items.TryGetValue("Nocturnal pill item ID from Studio", out IInventoryItem nocturnalPill) &&
nocturnalPill.isConsumeActive
);
}

private void OnItemConsumed(string itemID)
{
if (itemID == "Pizza item ID from Studio")
{
// Eating the pizza makes you jump!
if (SpatialBridge.actorService.localActor.avatar != null)
{
SpatialBridge.actorService.localActor.avatar.Jump();
SpatialBridge.actorService.localActor.avatar.AddForce(new Vector3(5f, 15f, 0f));
}
}
}
}

See IInventoryService for the full API reference.

Visual Scripting

Relevant scripting nodes that can help facilitate this are listed below:

  • Get Consumable Item State (asynchronous): gets relevant data for a given consumable item in the user’s backpack. The input trigger will need to be from a Coroutine since the request can be asynchronous and take time to complete if the item wasn’t found in the backpack.
    • Inputs
      • Item ID: The ID of the consumable item to get state for.
    • Outputs
      • Is Active: Returns true if the user has consumed the item in the past Duration seconds. This will always be false if the Duration is 0. In those cases, you will want the On Backpack Item Consumed event described below. The item can’t be consumed while the effects are active.
      • Duration Remaining: The number of seconds left before the item deactivates/expires. This will be 0 if the item is not active.
      • On Cooldown: Returns true if this item was deactivated in the past Cooldown seconds. The item can’t be consumed until this value is false (no longer on cooldown).
      • Cooldown Remaining: The number of seconds left on the cooldown timer. This will be 0 if there’s no cooldown in progress or if the item is still active.
  • On Backpack Item Consumed: An event node that executes when the specified item is consumed.
    • Inputs
      • Item ID: When this item with the specified ID is consumed, this event will execute.
  • On Backpack Any Item Consumed: An event node that executes when any item is consumed.
    • Outputs
      • Item ID: The ID of the item that was consumed.
  • On Consumable Item Duration Expired: An event node that executes when the consumable item’s duration expires and is deactivated.
    • Outputs
      • Item ID: The ID of the item that was consumed. After the set Duration for this item, this event will execute. This event will only execute if the item’s Duration is a positive number.

Scripting Graph Examples

The images below show two examples of how consumable items can be implemented.

When consumed, the frozen pizza makes your avatar jump and adds extra upwards force immediately after.

When consumed, the frozen pizza makes your avatar jump and adds extra upwards force immediately after. The frozen pizza consumable has no Duration set, so it only needs to listen to the On Backpack Item Consumed event for the pizza’s item ID. The On Consumable Item Duration Expired event will not be executed since the Duration was set to 0.

Nocturnal pill consumable example

The nocturnal pill example is a bit more complicated. The On Backpack Item Consumed event node is used as usual to activate the effect when it’s consumed. However, unlike the pizza example above, there is a Duration set for the item (in this case, 120 seconds). There needs to be an On Consumable Item Duration Expired event that needs to be listened for in order to deactivate the item’s effects after the Duration has elapsed.

Alternatively, you can constantly poll the state with Get Consumable Item State but that can be slower and/or less convenient. The logic will work as long as the user doesn’t leave the space during the item’s Duration, but will fail to activate the effects if they re-join the space while the item is active. This is fixed by using Get Consumable Item State when the scene initializes, which will get the initial value and activate the effects automatically.