Consumable Stats

Example Script

The script below demonstrates how to add an event that triggers whenever any item is used (consumed). It’s recommended to treat this as a reference and implement your own version if you need similar functionality.

using Esper.Inventool;
using Esper.Inventool.Items;
using Esper.Inventool.Stats;
using System.Collections;
using UnityEngine;

public class ConsumableEventExample : MonoBehaviour
{
    /// <summary>
    /// The player's stats.
    /// </summary>
    private CharacterStats characterStats;

    private void Awake()
    {
        // In this example, this component was added to the player object,
        // so we can get the character's stats with GetComponent
        characterStats = GetComponent<CharacterStats>();

        // Register the event on Awake
        Inventool.Inventory.onItemUsed.AddListener(OnConsumableUsed);
    }

    private void OnDestroy()
    {
        // Unregister the event when this object is destroyed
        Inventool.Inventory.onItemUsed.RemoveListener(OnConsumableUsed);
    }

    /// <summary>
    /// Handles consumable used.
    /// </summary>
    /// <param name="itemStack">The item stack used.</param>
    public void OnConsumableUsed(ItemStack itemStack)
    {
        // Safety null checks
        if (itemStack == null || !itemStack.item)
            return;

        // Ensure this is the correct item type
        if (itemStack.item.itemType.displayName != "Consumable")
            return;

        // Get the item dataset
        var dataset = itemStack.item.dataset as MyItemDataset;

        // Loop through each item stat
        foreach (var itemStat in itemStack.profile.stats)
        {
            // Check if the player has that specific stat
            var characterStat = characterStats.GetStat(itemStat.Identity);

            if (characterStat != null)
            {
                // If so, apply the consumable
                switch (dataset.consumableType)
                {
                    case MyItemDataset.ConsumableType.Restoration:
                        if (!dataset.isOverTime)
                        {
                            // Restore immediately
                            characterStat += itemStat;
                        }
                        else
                        {
                            // Restore over time
                            StartCoroutine(RestorationHelper(characterStat, itemStat, dataset.consumableLength));
                        }
                        break;

                    case MyItemDataset.ConsumableType.Buff:
                        // Apply the buff (with auto removal)
                        StartCoroutine(BuffHelper(characterStat, itemStat, dataset.consumableLength));
                        break;
                }
            }
        }
    }

    /// <summary>
    /// A coroutine that assists with over-time stat restoration (each tick delayed by a second).
    /// </summary>
    /// <param name="characterStat">The charater stat to restore.</param>
    /// <param name="itemStat">The stat to use as the restoration source.</param>
    /// <param name="length">The duration of the consumable's effect.</param>
    /// <returns>An enumerator that performs over-time stat restoration when used as a coroutine.</returns>
    private IEnumerator RestorationHelper(Stat characterStat, Stat itemStat, float length)
    {
        // Calculate ticks based on length (1s = 1 tick, 1.5s = 2 ticks)
        var ticks = Mathf.CeilToInt(length);

        // Calculate value added per tick
        var overTimeValue = itemStat.value / ticks;

        // Tick loop
        for (int i = 0; i < ticks; i++)
        {
            // Restore the stat
            characterStat += overTimeValue;

            // Yield for a second before the next tick
            yield return new WaitForSeconds(1f);
        }
    }

    /// <summary>
    /// A coroutine that assists with buffs. The buffs are removed automatically.
    /// </summary>
    /// <param name="characterStat">The charater stat to apply the buff to.</param>
    /// <param name="itemStat">The stat to use as a buff.</param>
    /// <param name="length">The duration of buff.</param>
    /// <returns>An enumerator that performs over-time stat restoration when used as a coroutine.</returns>
    private IEnumerator BuffHelper(Stat characterStat, Stat itemStat, float length)
    {
        // Apply the buff
        characterStat.Combine(itemStat);

        // Yields for the duration length
        yield return new WaitForSeconds(length);

        // Remove the buff
        characterStat.Uncombine(itemStat);
    }
}

Important Notes

  • It’s recommended to enable Update Current Value With High Value in the Stat Identity settings if you want buffs to affect the current value as well (by default, only the high value is modified).

  • The dataset below must be set up.

  • This script is a component and must be attached to the same GameObject that holds the player's CharacterStats component.

  • Supports both instant and over-time stat restoration consumables.

  • Uses coroutines for over-time effects — if a coroutine is interrupted (e.g., the GameObject is disabled), over-time affects may be canceled and buffs may not be properly removed. You’ll need to implement your own stat-tracking logic to handle such cases.

  • No UI functionality is included in this script.

Dataset Used

This is the custom item dataset used for the example above. Click here to learn more about datasets.

using Esper.Inventool.Items;
using UnityEngine;

[CreateAssetMenu(fileName = "My Item Dataset", menuName = "Inventool/Datasets/My Item Dataset")]
public class MyItemDataset : Dataset
{
    /// <summary>
    /// The type of consumable.
    /// </summary>
    public ConsumableType consumableType;

    /// <summary>
    /// The duration of the consumable's effect (e.g., buff duration or restoration period).
    /// Ignored for consumables that apply their effect instantly.
    /// </summary>
    [Min(0)]
    public float consumableLength;

    /// <summary>
    /// Determines whether the consumable's effect is applied gradually over time instead of instantly.
    /// Ignored for buffs.
    /// </summary>
    public bool isOverTime;

    /// <summary>
    /// Specifies how a consumable item affects the player's stats.
    /// </summary>
    public enum ConsumableType
    {
        /// <summary>
        /// Uses the item's stats to restore or replenish a specific stat (e.g., health or mana).
        /// </summary>
        Restoration,

        /// <summary>
        /// Applies the item's stats as a temporary buff that enhances attributes for a limited duration.
        /// </summary>
        Buff
    }
}

Last updated