Move Items (Drag & Drop)
Use the same movement rules to let a player drag Items with a pointer or move them with keyboard or controller input. A shared cursor shows the Item being moved, while each destination container uses an Item View Drop Handler and an ordered Drop Action Set to accept, reject, move, transfer, or exchange the underlying ItemInfo.
The cursor is only a visual preview. A successful Bag-to-Equipment move must change the Inventory or Item Collection through the destination container; moving an Icon between slots is not an Inventory transaction.
Before you begin
Create and bind the participating Item View Slots Containers first. For the examples below:
- Bag is an Inventory Grid containing Health Potion and Iron Sword;
- Equipment is an Item Slot Collection View with a Weapon slot;
- the Equipment collection and its visible Item View Slot both reject Health Potion; and
- both containers belong to the same player Inventory and active Display Panel Manager.
Create a project-owned Drop Action Set rather than editing an asset inside the package. Use one set for containers that should follow the same movement policy, or separate sets when Bag, Equipment, hotbars, and world-drop destinations require different outcomes.
Add movement in UI Designer
- Open Tools > Opsive > Ultimate Inventory System > UI Designer and select the tab for the generated container, such as Inventory Grid or Equipment.
- Select the intended generated container and open Moving Items in its Item View Slots Container options.
- Under Cursor Manager, choose Create if the player’s Canvas does not already contain an Item View Slot Cursor Manager. One manager can serve several containers for the same player.
- Under Drop Handler, choose Create, then assign Item View Slot Drop Action Set. Add a Drop Handler to every container that can be a destination.
- Under Drag Handler, choose Create on every container from which pointer dragging may begin.
- Under Move Cursor, choose Create on every container that supports the keyboard/controller Move Item Action.
- Add the Move Item Action to the Item Action Set used by that container. The action is available only when an Item View Slot Move Cursor exists beside the container.
- Add Item Action bindings and other conflicting container bindings to Unbind While Moving so selecting the destination does not also consume, equip, or otherwise use the Item.
UI Designer adds the Cursor Manager to the parent Canvas, and adds the Drop Handler, Drag Handler, and Move Cursor to the selected container. Creating the Move Cursor also creates a Move Cursor Panel beneath the container’s Display Panel content.
Configure the Item View Slot Cursor Manager
The Item View Slot Cursor Manager records the source slot and creates a floating Item View while a move is active. It registers by ID, so containers and Drop Handlers can find the correct manager without a direct reference.
| Inspector field | Version 1 default | Use |
|---|---|---|
| ID | 1 |
Identifies this manager. Use a distinct ID for each local player’s movement UI. |
| Canvas | None | Parent Canvas used for the floating Item View. The component finds its parent Canvas when this is unassigned. |
| Position Offset | (0, 0) |
Adds an offset to the floating view position. |
| Use Container To Spawn Item View | On | Uses the source container’s matching Item View prefab for the floating view. |
| Category Item View Set | None | Supplies the floating prefab when Use Container To Spawn Item View is off. |
| On Start Move Event / On End Move Event | Empty | Optional visual, audio, or input feedback around the pending move. |
Only one floating Item View can be active on a manager. The source Item View and floating Item View notify modules that implement the movable interface, allowing the source to dim and the floating view to use a moving state. The floating prefab needs a Canvas Group; movement disables its interaction and raycasts so the destination slot can receive the drop.
When the source container closes, the manager cancels pointer movement and redraws the source container. A missing floating prefab produces a warning and leaves no useful movement preview, so verify the container’s Item View prefab or the fallback Category Item View Set.
Configure the Item View Drop Handler
Add an Item View Drop Handler to each potential destination container. It listens to that container’s selection, deselection, click, and pointer-drop events, combines them with the cursor manager’s source data, and evaluates the assigned action set.

| Inspector field | Version 1 default | Use |
|---|---|---|
| Cursor Manager ID | 1 |
Finds a registered Cursor Manager when no direct reference is assigned. |
| Item View Slot Cursor Manager | None | Optional direct manager reference; the handler otherwise checks the ID and then its parents. |
| Drop On Last Selected View | Off | Off uses the slot that received the pointer drop. On redirects the drop to the last selected slot, which is useful only when selection is the intended destination. |
| On Select Can Drop Event / On Select Cannot Drop Event | Empty | Optional feedback while a pending Item hovers or navigates over a destination. |
| On Drop Success Event / On Drop Fail Event | Empty | Optional feedback after a rule matches or no rule matches. |
| Item View Slot Drop Action Set | None | Required ordered conditions and actions for the destination. |
The handler also notifies Item View Modules that implement the drop-hover interface. Use those modules to show valid and invalid destination states. That preview is based on the first passing rule; it does not move the Item.
For pointer movement, the source and destination event data must have the same pointer ID. For keyboard/controller movement, the Drop Handler treats a click or submit on the selected slot as the drop.
Define the Drop Action Set
Create an asset with Create > Ultimate Inventory System > UI > Item View Slot Drop Action Set, then assign it to every participating Drop Handler that should share the policy.

A new Version 1 set starts with two ordered groups:
| Order | Conditions | Actions | Outcome |
|---|---|---|---|
| 1 | Container Can Move | Move Index | Moves or swaps Item Stack indexes within the same compatible container. |
| 2 | Container Can Smart Exchange | Container Smart Exchange | Transfers the source to another compatible container and returns the destination Item when the reverse leg is valid. |
The groups are evaluated from top to bottom. Every condition in a group must pass, the actions in the first passing group run in list order, and later groups are ignored. Keep specific rules before broad rules.
For the Bag and Equipment example:
- moving Iron Sword between two Bag positions uses Move Index;
- moving Iron Sword from Bag to an empty Weapon slot uses Container Smart Exchange;
- dropping Iron Sword onto an occupied compatible Equipment slot can exchange the Items when both directions are valid; and
- moving Health Potion to the Weapon slot fails because the destination container or visible slot rejects it.
Container Can Smart Exchange checks source give permission, destination add permission, and both visible slot restrictions. Enforce Two Way Check is off by default, so a valid source-to-destination leg may pass even when the reverse leg cannot. Enable it when an occupied destination must be able to return its Item to the source.
Amounts, stacks, swaps, and overflow
The standard movement path carries the current source ItemInfo, including its current amount and Item Stack reference. It does not show a quantity prompt or split a stack. Add a separate quantity workflow before starting movement when the player must move only part of a Health Potion stack.
The specialized container decides what an index means and how Items are stored:
- Inventory Grid moves indexed Item Stacks and adds through its Inventory;
- Item Slot Collection View swaps Item Slot Collection entries and applies its slot restrictions;
- Item Shape Grid requires its shape-aware condition and action; and
- hotbars can represent assignments or mirrored Inventory positions rather than owning another Item Stack.
Conditions must account for collection capacity, slot restrictions, and the destination’s add behavior before an action removes the source. Drop actions execute sequentially and the Drop Action Set does not provide a general transaction rollback or overflow destination. A custom Give or Exchange action paired with incomplete conditions can remove an Item before a later add fails.
Container Smart Exchange also needs full-amount validation when restrictions can admit part of a stack. Inventory Grid’s Boolean check accepts a non-null partial result, and Smart Exchange removes the source without checking the actual added amount. With Return Overflow off, a ten-Item move into space for two can lose eight. Add a condition that requires the full amount before removal, or use a tested custom transfer that returns every rejected remainder. Test partial capacity as well as entirely full and occupied destinations.
Add pointer drag-and-drop
The Item View Slot Drag Handler belongs beside the source container. Its important fields are:
| Inspector field | Version 1 default | Effect |
|---|---|---|
| Item View Slot Cursor Manager | None | Finds a manager in the parents when unassigned. |
| Disable Drag On Empty Slot | On | Prevents a drag from starting when the slot has no Item. |
| Keep Offset | On | Starts the floating view from the source slot position and then applies pointer movement. |
| Mouse Input | Left, Right, and Middle | Allows all three pointer buttons unless narrowed. |
| On Drag Started Event / On Drag Ended Event | Empty | Optional feedback around the pointer gesture. |
The runtime sequence is:
- the source container raises its begin-drag event;
- the Drag Handler validates the pointer button and nonempty source;
- the Cursor Manager records the source
ItemInfo, container, slot, local index, index offset, and pointer ID, then creates the floating view; - the Drag Handler moves the floating view by the pointer delta;
- destination selection asks its Drop Handler which rule would pass and can update hover feedback;
- the pointer drop runs the first passing action group on the matching destination; and
- the cursor is removed and affected containers redraw.
Limit Mouse Input to the controls used by the project. Leaving all three buttons enabled can start movement from a button reserved for context menus or another action.
Add keyboard or controller movement
The Move Item Action starts an Item View Slot Move Cursor from the currently selected slot. Navigation then moves the selection and floating view. Clicking or submitting the destination sends it through the same Drop Handler and Drop Action Set used by pointer input.

| Inspector field | Version 1 default | Use |
|---|---|---|
| Move Display Panel | None when added manually | UI Designer creates and assigns a Move Cursor Panel. |
| Unbind While Moving | Empty | Temporarily unbinds listed Item View Slots Container bindings during the pending move. |
| Unbind Interface While Moving | Empty | Finds and unbinds container-binding interfaces on the listed GameObjects. |
| On Move Start / On Move End / On Move Canceled | Empty | Optional movement feedback. |
| Draw On Move End | On | Redraws the bound container after a completed move. |
| Draw On Move Cancel | On | Redraws after the component’s cancel path. |
Add the Item Action binding that normally opens Use, Equip, or another action to Unbind While Moving. Otherwise the submit used to place Iron Sword can also invoke its normal Item Action.
Version 1 cancel boundary
The released Version 1 source describes the Move Display Panel as a way to cancel with the panel’s back input, but its ItemViewSlotMoveCursor.CancelMove() guard returns while a move is active. Do not rely on that tooltip without testing the exact package revision. If closing the panel leaves the floating view active, update to a release containing the correction or route the cancel input through the Cursor Manager’s public CancelMove() method and verify the move-end and panel-close events together.
Pending movement is transient. Always test cancel, panel close, source-container close, and interrupted input as separate cases.
Editor checkpoint
Before entering Play Mode, confirm that:
- the player’s Canvas has one Item View Slot Cursor Manager with the intended ID and Canvas;
- every container resolves that manager through Slot Cursor or Slot Cursor ID;
- every destination has an Item View Drop Handler with the same manager ID and an assigned Drop Action Set;
- the default Container Can Move rule appears before Container Can Smart Exchange;
- Bag and Equipment have the correct Inventory and Item Collection bindings;
- the Equipment Weapon slot has both its collection restriction and matching Item View Slot restriction;
- every pointer source has an Item View Slot Drag Handler with the intended Mouse Input;
- every keyboard/controller source has an Item View Slot Move Cursor and a Move Item Action;
- conflicting Item Action bindings appear under Unbind While Moving;
- the floating Item View prefab has a Canvas Group and readable moving state;
- valid and invalid drop-hover feedback can be distinguished; and
- the Move Display Panel cancel path has been verified in this exact Version 1 package.
Verify in Play Mode
- Drag Iron Sword between two Bag slots. Confirm that the Item Stack index changes once and no duplicate appears.
- Drag Iron Sword from Bag to an empty Equipment Weapon slot. Confirm that Bag, Equipment, and the underlying collections all update.
- Drag Health Potion to the same Weapon slot. Confirm that invalid feedback appears and the Potion remains in Bag.
- Fill or restrict the destination, then repeat the Iron Sword drop. Confirm that rejection does not remove the source or route it to an unexpected collection.
- Put a compatible Item in both source and destination and verify the intended exchange in both directions.
- Drag a stack of Health Potions and confirm that the configured movement rule handles the entire displayed amount; no split prompt should appear in the standard flow.
- Repeat valid and invalid moves with the keyboard/controller Move action. Confirm that destination submit does not also invoke Use or Equip.
- Cancel an active pointer move, close the source panel, and test the Move Cursor panel’s back input separately. Confirm that the floating view, source dimming, hover preview, and pending state all clear.
- With local multiplayer, repeat the move for each player and confirm that each cursor, EventSystem, Inventory, and panel affects only its owner.
Save and network boundaries
The Cursor Manager, floating Item View, selected destination, hover result, pointer ID, and pending Move Cursor state are UI state and are not saved. Save the authoritative Inventory, Item Collections, mutable Items, and any supported hotbar or grid-position data, then redraw the containers after loading. Do not restore a move that was in progress when saving.
These Version 1 movement components do not provide network authority, prediction, rollback, or replication. A multiplayer implementation must validate the requested Inventory transaction on the authority, synchronize the resulting Inventory or collections, and redraw each client’s local UI. Do not replicate the floating Icon as proof that the Item moved.
Troubleshooting
| Symptom | Check | Fix |
|---|---|---|
| Dragging never starts | Drag Handler, Disable Drag On Empty Slot, Mouse Input, and slot raycasts | Add the handler to the source, use an allowed pointer button, and confirm the source contains an Item. |
| The source dims but no floating Item appears | Cursor Manager Canvas, container Item View prefab, fallback Category Item View Set, and Canvas Group | Assign a usable floating prefab and Canvas Group, then verify the manager’s Canvas. |
| The floating Item appears but every drop fails | Destination Drop Handler and Item View Slot Drop Action Set | Add the handler to the destination and assign an initialized action set. |
| A drop uses the wrong slot | Drop On Last Selected View, pointer selection, and destination event data | Leave the option off for pointer-position drops, or make selection the deliberate destination. |
| Health Potion enters a Weapon slot | Equipment collection restriction, visible slot restriction, and smart-exchange condition | Apply the Weapon restriction at both data and UI layers and keep the validation condition before the action. |
| An Item disappears when the destination is full | Custom action order and capacity conditions | Require the full accepted amount before removing the source, or implement and verify remainder rollback. Smart Exchange alone does not handle a partial destination result safely. |
| Only the Icon moves | Action group and specialized container action | Use Move Index, Container Smart Exchange, or another action that changes the underlying data. |
| A partial stack cannot be moved | Standard movement carries the full source ItemInfo |
Ask for an amount and create the partial ItemInfo in a separate quantity workflow before moving. |
| Pointer drop ends on a different pointer | Source and destination pointer IDs | Keep the drag and drop on the same pointer and EventSystem. |
| Controller placement also consumes or equips the Item | Unbind While Moving | Add the Item Action binding and any conflicting binding to the Move Cursor’s unbind list. |
| Back closes the panel but leaves movement active | Version 1 Move Cursor cancel guard | Verify the installed patch and route cancel through the Cursor Manager’s CancelMove() when required. |
| Valid/invalid hover colors never change | Drop-hover Item View Module and feedback events | Add a compatible preview module or connect the select-can-drop and select-cannot-drop events. |
| The wrong player’s Item moves | manager ID, container Slot Cursor ID, panel owner, and EventSystem | Give each local player a distinct manager and bind every container to the matching owner. |
| A saved game restores stale movement UI | saved data and post-load redraw | Save authoritative Inventory state only, clear pending movement, and redraw after load. |
Related pages
- Item View Slots Container
- UI Designer common container options
- Item View Slot
- Inventory Grid
- Equipment Item Slot Collection View
- Item Shape Grid
- Item Hotbar
- Item Actions
- Input handlers
- Save system
Developer details
ItemViewSlotDropHandlerStreamData records the source and destination containers, slots, ItemInfo values, local slot indexes, and index offsets. Its SourceIndex and DestinationIndex are the local slot index plus the relevant container offset. Conditions should treat this data as read-only; actions may update it with the actual Item removed before a later action adds that Item.
The Drop Action Set exposes GetFirstPassingConditionIndex, GetFirstPassingCondition, and HandleItemViewSlotDrop. A return value of -1 means no group passed. The Drop Handler’s success event means a group matched and its actions ran; it is not a separate verification that every custom data mutation succeeded.
Important runtime APIs include:
ItemViewSlotCursorManager.StartMove,CancelMove,BeforeDrop,RemoveItemView,SetPosition, andAddDeltaPosition;ItemViewDropHandler.HandleItemViewSlotDrop,ItemViewSlotSelected, andItemViewSlotDeselected;ItemViewSlotDropActionSet.HandleItemViewSlotDropandGetFirstPassingConditionIndex;ItemViewSlotsContainerBase.CanAddItem,CanGiveItem,CanMoveItem,AddItem,RemoveItem, andMoveItem; andItemViewSlotMoveCursor.StartMove(int).
Version 1 also includes conditions for container add/give/move, container name, source Item Collection, source amount, null source or destination, same-container matching, smart exchange, and Item Shape placement. Actions include container give/remove/exchange/smart exchange, Inventory give/exchange, move index, Item Action invocation, Item Object spawning, audio playback, and Item Shape placement.
Create a custom rule by deriving from ItemViewDropCondition or ItemViewDropAction:
[Serializable]
public class SameContainerCondition : ItemViewDropCondition
{
public override bool CanDrop(ItemViewDropHandler handler)
{
return handler.SourceContainer == handler.DestinationContainer;
}
}
[Serializable]
public class MoveIndexAction : ItemViewDropAction
{
public override void Drop(ItemViewDropHandler handler)
{
handler.SourceContainer.MoveItem(
handler.StreamData.SourceIndex,
handler.StreamData.DestinationIndex);
}
}
Keep conditions free of mutations, place capacity and restriction checks before removal actions, and test every custom rule with an empty, occupied, restricted, full, and invalid destination.