Item Object Behaviour Handler
Use an Item Object Behaviour Handler when an equipped Item needs GameObject behavior that player input or project code can trigger. An Iron Sword can call a melee component, while a Fire Wand can call a projectile component and obtain its values from the equipped Item.
The handler does not provide a general attack, spell, or consume system. It maps an action index to a project-specific Item Object Behaviour, checks whether that behavior can run, and passes it the equipped Item Object and Item User.
| Goal | Use |
|---|---|
| Swing an equipped Iron Sword or cast with an equipped Fire Wand | Item Object Behaviour Handler on the usable Item Object prefab |
| Drink a Health Potion directly from Bag | An Item Action, unless the potion is deliberately equipped or spawned as an Item Object |
| Move an Item between Bag and Equipment | An Item Action or Inventory UI transaction; the behavior handler does not move Items |
Before you begin
Prepare the equipment workflow before adding usable behavior:
- an initialized Inventory System Manager and database;
- a player Inventory with Bag and a slot-based Equipment collection;
- an Item Slot Set shared by the Equipment collection and Equipper;
- an Item User and player input implementation on the character;
- an Equipper configured for the Equipment collection; and
- valid
EquipmentPrefaband, when needed,UsableItemPrefabGameObject attributes.
See Equipping Items for the complete collection, slot, prefab, and Equipper setup.
Build an Iron Sword usable prefab
This workflow uses action index 0 for a sword attack.
- Create a prefab that will be the sword’s functional Item Object. Add Item Object to its root.
- Add the project’s melee component to the same root. The component must inherit
ItemObjectBehaviourand implementUse. - Add Item Object Behaviour Handler to that root.
- Leave Item Object empty when the Item Object component is on the same GameObject. The handler finds it in
Awake. Assign the field explicitly only when the handler intentionally targets another Item Object. - Set Item Object Behaviours to size
1and assign the melee component to element0. - On the Iron Sword Definition, assign the visible sword model to
EquipmentPrefab. Assign the functional prefab toUsableItemPrefabwhen the visual and behavior roots are separate. - If Attack or another Item attribute should configure the melee component, add Item Binding to the usable root and bind that attribute to a public property on the component. See Item Binding.
The array order is the action contract. Element 0 is action index 0, element 1 is action index 1, and so on. The handler does not search the prefab for behaviors or identify them by name.
Editor checkpoint
Before entering Play Mode, confirm that:
- Iron Sword has a non-null
EquipmentPrefab; UsableItemPrefabis either absent or references a valid functional prefab;- the functional root contains Item Object, Item Object Behaviour Handler, and the melee behavior;
- every Item Object Behaviours element contains the intended component; and
- each configured action index matches the array element that should run.
Connect character input
Add Usable Equipped Items Handler to the character that owns the Equipper and Item User.
- Assign Item User, or leave it empty only when Item User is on the same GameObject.
- Add an element under Inputs.
- Leave Input Type as Button Down for a one-use-per-press action, or deliberately choose another supported input type.
- Set Input Name to the project input mapped to the sword attack.
- Set Item Object Index to the sword’s index in the Equipper’s Item Object Slots list.
- Set Action Index to
0for the first behavior in the sword handler.
The released Version 1 defaults for each input are Button Down, an empty Input Name, Long Press Duration 0.5, Wait For Long Press Release off, Item Object Index 0, and Action Index 0. Supply a real Input Name unless Automatic or a project-controlled route is intentional.
Item Object Index and Action Index identify different things. Item Object Index selects an equipped slot; Action Index selects a behavior on the Item Object in that slot.
How it runs
When the configured input is detected:
- Usable Equipped Items Handler asks the Equipper for the Item Object at Item Object Index.
- It looks for an
IItemObjectBehaviourHandleron that Item Object’s root GameObject. - Item Object Behaviour Handler validates Action Index and gets that array element.
- If the component exists and its
CanUseproperty is true, the handler callsUse. Usereceives the exact equipped Item Object and the character’s Item User, so project code can read Item attributes or reach character gameplay systems.
An input is ignored when the slot is empty, the Item Object root has no handler, the action index is outside the array, or CanUse is false. A null behavior element logs a warning. The handler does not queue a blocked use or return a success result.
The Usable Equipped Items Handler disables itself when its player’s gameplay-input event disables input. This prevents configured uses while another system has turned off gameplay input, provided the project sends that event through the same player input GameObject.
Understand prefab ownership
The default Equipper always requires EquipmentPrefab.
- When
UsableItemPrefabis absent,EquipmentPrefabbecomes the Item Object root. Put the handler and behavior on that prefab. - When
UsableItemPrefabexists, it becomes the functional Item Object root and the equipment model is created beneath it. Put the handler and behavior on the usable prefab, not only on the visual model.
This placement matters because Usable Equipped Items Handler checks the Item Object’s root GameObject; it does not search child objects for the handler.
The Equipment collection remains the source of truth. Adding Iron Sword to an Equipment slot makes the Equipper create or reuse the functional root and visual model. Removing it clears the slot and destroys or returns those objects to their pools. The behavior handler does not equip, unequip, pick up, or drop the Item by itself.
Control cooldowns
Every Item Object Behaviour begins usable. Its default CanUse returns true when Time.time is greater than or equal to its protected m_NextUseTime value.
A custom behavior owns its cooldown. During Use, set m_NextUseTime to Time.time + cooldown. The handler does not do this automatically. Each behavior component has its own value, so an attack and a reload stored at different action indexes can use independent cooldowns.
Keep these timing choices in mind:
- Button Down requests one use for each completed press and release.
- Button Down Continuous can request a use every frame while the button is held;
CanUsemust prevent unwanted repeats. - Automatic requests a use every Update and runs again as soon as the behavior becomes available.
Time.timeuses scaled game time, so a paused or slowed time scale also pauses or slows the default cooldown.- Input during a cooldown is discarded rather than buffered.
An Item Object returned to the Version 1 pool is disabled, not reconstructed. Its nonserialized m_NextUseTime field can therefore remain set if the same instance is reused during the same session. Reset the value in project code only when immediate reuse after re-equipping is the intended design.
Apply the pattern to common Items
Iron Sword
Use a custom melee behavior at action index 0. The behavior can read Attack from the Item Object’s Item, obtain the character combat component through Item User, start animation and collision timing, and then advance m_NextUseTime.
Fire Wand
Use a custom ranged behavior at action index 0. An Item Binding can copy Attack and project-specific values such as projectile count or projectile prefab into public properties on that behavior. The behavior then launches the projectile and applies its own cooldown. Keep the wand model in EquipmentPrefab and reusable casting logic in UsableItemPrefab when several Definitions share the same implementation.
Health Potion
For a Health Potion selected in Bag, use an Item Action so the command keeps the selected Item Info and collection context, applies healing, and removes the correct amount. Use an Item Object Behaviour only when the potion is represented as an equipped or world Item Object and should follow this component-and-input route.
Verify in Play Mode
- Put Iron Sword in Bag, equip it into the expected Equipment slot, and confirm that the Equipper creates an Item Object in the matching Item Object Slots entry.
- Press the configured input once. Confirm that only the behavior at the configured action index runs and receives Iron Sword and the expected Item User.
- Press again before the cooldown ends. The second use should be ignored without starting another attack.
- Press after the cooldown. The behavior should run again exactly once.
- Equip Fire Wand into the same or another configured slot. Confirm that Item Binding applies its values before the first cast and that the input selects the correct slot and action.
- Unequip the Item and press the input. No behavior should run while the selected slot is empty.
- Disable gameplay input through the character’s normal input-gating flow. The handler should stop responding until gameplay input is enabled again.
Saving and multiplayer
Inventory saving restores the Equipment collection; the Equipper then recreates the appropriate Item Objects from their prefab attributes. The behavior array and its serialized settings belong to the prefab and do not need a separate save record.
The default system does not save an in-progress use, the remaining m_NextUseTime, a running behavior coroutine, or other custom gameplay state. Store persistent cooldowns or charges in a saved Item attribute or a project saver when they must survive loading.
Released Version 1 does not replicate Item Object Behaviour calls or enforce multiplayer authority. In a networked project, let the authoritative side validate the equipped Item, action index, cooldown, resource costs, and resulting damage or projectile. Replicate the accepted result rather than allowing each client to apply it independently.
Troubleshooting
| Symptom | Check | Fix |
|---|---|---|
| Input does nothing | Check Item User, the player input implementation, Input Name, and gameplay-input gating. | Put the required components on the same character or assign Item User explicitly, then test the input mapping while gameplay input is enabled. |
| The wrong equipped Item responds | Compare Item Object Index with the ordered Item Object Slots generated by the Equipper’s Item Slot Set. | Use the zero-based slot index for the intended Equipment slot. |
| The wrong behavior runs | Compare Action Index with the Item Object Behaviours array order. | Reorder the array or update the input’s action index; indexes are positional. |
| The equipped model appears but cannot be used | Inspect which prefab is the functional Item Object root and whether the handler is on that root. | Put the handler and behavior on UsableItemPrefab, or on EquipmentPrefab when no usable prefab is defined. |
| The Console warns that an action component is null | Inspect the selected Item Object Behaviours element. | Assign a behavior component to every reachable element or remove the unused entry. |
| Holding input triggers too often | Check Input Type and whether the custom behavior advances m_NextUseTime. |
Use Button Down for one use per press and set the next-use time when the behavior runs. |
| The Item remains unavailable after a quick unequip and re-equip | Check whether the pooled behavior instance still has a future next-use time. | Keep that continuity when it is intended, or reset the custom cooldown when the usable object is enabled. |
| Fire Wand uses default values instead of Item attributes | Check the Item Binding’s source, attribute names, target component, and public property paths. | Keep Item Binding on the usable root and bind each correctly typed attribute to a public property. |
Current Version 1 boundaries
- The framework supplies the handler and base behavior. Actual attacks, spells, consumable effects, and character rules are project-specific; the demo’s melee and ranged behaviors are examples, not general runtime actions.
- Item Object and action selection are positional integer indexes. There is no name lookup, action priority, or automatic remapping when array order changes.
- The input route finds the behavior handler only on the equipped Item Object’s root.
- The built-in input check handles Automatic, Button Down, Button Down Continuous, Double Press, Long Press, Tap, and Axis. Manual and Custom enum values do not invoke an action through
SimpleInput.CheckInput; callUseItemor add project input code for those routes. - A blocked cooldown, invalid index, empty slot, or missing handler is ignored without a result event. Only a null behavior element produces the handler’s warning.
- Cooldown state is per component, uses scaled time, is not saved, and may remain on a pooled instance during the current session.
- The behavior handler has no built-in save, networking, cost, animation, projectile, damage, or use-completed event layer.
Related pages
- Item Objects explains the relationship between Items and their scene GameObjects.
- Equipping Items configures Equipment collections, slots, prefab attributes, and the Equipper.
- Item Binding copies Item attributes into public component properties.
- Item Actions covers inventory-side commands such as drinking, equipping, and dropping.
- Input Handlers covers the wider Version 1 input routes.
- Item Slot Collection explains slot-based Equipment ownership.
- Save System covers Inventory and Item persistence.
- Events lists the framework event pattern used by equipment and inventory systems.
Developer reference
A custom behavior inherits ItemObjectBehaviour. Set its next-use time when the action is accepted, then call the project’s gameplay system with the Item Object and Item User context.
using Opsive.UltimateInventorySystem.Core;
using Opsive.UltimateInventorySystem.ItemActions;
using Opsive.UltimateInventorySystem.ItemObjectBehaviours;
using UnityEngine;
public sealed class FireWandCast : ItemObjectBehaviour
{
[SerializeField] private float m_Cooldown = 0.5f;
public override void Use(ItemObject itemObject, ItemUser itemUser)
{
m_NextUseTime = Time.time + m_Cooldown;
// Read the equipped Item and call the project's projectile system.
var item = itemObject.Item;
}
}
The main runtime entry points are:
ItemObjectBehaviour.CanUseandUse(ItemObject, ItemUser)for behavior eligibility and execution;ItemObjectBehaviourHandler.UseItem(ItemUser, int)for direct use of one action index; andUsableEquippedItemsHandler.UseItem(int, int)for direct selection by equipped-slot index and action index.
The Equipper publishes its standard equipped, unequipped, and changed events when the Equipment collection changes. The behavior handler does not publish a use event, so a project that needs started, completed, canceled, cooldown, or resource-consumed notifications must define those around its gameplay behavior.