🧪 Use (Items & Effects)¶
The Use folder handles consuming items and running their effects from inventory.
- ItemUseSystem → consumes exactly 1 item and applies its effects
- IUseEffect / UseEffectObject → native, ScriptableObject-friendly effect interface
- UseEffectResolver → turns ScriptableObjects into runnable effects
- Adapters → optional bridges (e.g. Pickups) so third‑party effects can act as inventory use-effects
🚀 Quickstart¶
- Add
ItemUseSystemto a GameObject (typically the player or a gameplay manager). - Ensure usable items have
usable = trueand one or moreuseEffectsassigned inItemDefinition. - Call:
var result = useSys.UseResult(player, slotIndex: 0);
if (!result.Success)
Debug.LogWarning($"Use failed: {result.Code} {result.Message}");
Execution Flow¶
- Resolves the configured container (Unity-facing string →
ContainerId, default ="Backpack"). - Resolves each
useEffectviaUseEffectResolver. - Executes effects in order.
- If at least one effect applies, exactly 1 item is consumed from the slot.
🧩 Effects¶
Native Effects (IUseEffect)¶
public interface IUseEffect
{
bool AllowsNullDamageable { get; }
void Apply(IDamageable dmg, GameObject target);
}
Implementation Options¶
- Code-only — implement
IUseEffectdirectly - ScriptableObject — derive from
UseEffectObject : ScriptableObject, IUseEffect
Sample Native Effects (Samples)¶
- DebugPingEffect — logs a message
- SpawnVfxEffect — spawns a prefab
Assign these assets to ItemDefinition.useEffects[] and set usable = true.
🔌 UseEffectResolver¶
Central routing point that maps a ScriptableObject → IUseEffect.
Resolution Order¶
-
Native
If the ScriptableObject already implementsIUseEffect, use it directly. -
External Adapters
Registered via:
UseEffectResolver.ExternalResolvers += MyResolver;
(The Pickups adapter registers itself here when REV_PICKUPS_PRESENT is defined.)
- Fallback
If no resolver returns a non-null effect, the effect is skipped silently.
Example¶
if (UseEffectResolver.TryResolve(effectSO, out var effect))
effect.Apply(dmg, target);
🔌 Pickups Integration (Optional)¶
Enabled when:
#define REV_PICKUPS_PRESENT
Features:
PickupEffectassets and decorated definitions become usable as inventory effects- Context-aware execution via
ItemUseContext: owneritemDefslotIndex- Routed internally through
PickupEffectInvokerfor a single execution choke point
Key files:
Inventory/Bridges/Pickups/Internal/PickupEffectInvoker.csUseEffectResolver.PickupsAdapter.cs
🎯 Targeting & Damageable Resolution¶
ItemUseSystem determines the target in this order:
effectTargetOverridedefaultEffectTargetownerWithInventory
It then resolves an IDamageable on:
- the target
- a child of the target
- a parent of the target
If an effect does not allow null damageables (AllowsNullDamageable == false)
and none is found, that effect is skipped.
🍽️ Consumption Semantics¶
- Effects execute in order.
- Only effects that resolve and apply count as applied.
- If none apply → the item is not consumed.
- If one or more apply → exactly 1 item is removed.
- Removal uses the service-level authority-gated path:
var rmRes = svc.RemoveFromSlot(ownerWithInventory, cid, slotIndex, 1);
If authority denies removal, the entire use fails.
⚠️ Gotchas¶
- Authority: final removal is enforced by
SceneInventoryService; may returnNoAuthority. - Null targets: provide
defaultEffectTargetif effects expect a damageable. - Ordering matters: effects run exactly in the order defined in
useEffects[]. - Durability & Meta: unchanged — only quantity is affected.
- Pickups effects: require
REV_PICKUPS_PRESENTto resolve. - Exception safety: if a custom effect throws, consumption does not occur.
🧭 World Pickups (Bonus)¶
Under Use/World/:
- ItemPickup2D — adds an item to inventory and destroys itself
- UnifiedPickup2D — (with Pickups) run effect, add item, or both
Useful for world pickups, puzzle items, and lightweight prototypes.