Quick answer: Don’t Set Position in the same event that the Drag & Drop behavior is acting. Let the behavior own position, or only set it on Drop, not on Drag.
An inventory item with Drag & Drop snaps to the layout origin the instant it’s grabbed. A competing Set Position action zeroes it.
The Conflict
The Drag & Drop behavior sets the object’s position to follow the pointer. If another event also runs Set Position (e.g. “Every tick: Set position to snap_x, snap_y” with uninitialized vars), the two fight and the uninitialized one (0,0) often wins.
Let the Behavior Own Position
On DragDrop drag start:
→ (do nothing to position)
// behavior handles position automatically
While dragging, don’t touch position. The behavior does it.
Snap on Drop Only
On DragDrop drop:
Set position to (round(Self.X / grid) * grid, round(Self.Y / grid) * grid)
Snap-to-grid happens once, on drop — not every frame.
Grab-Point Offset
If the object jumps so the pointer is at its origin (top-left) instead of where you grabbed, record the offset on drag start and re-apply — or set the object’s origin to its center.
Verifying
Grab an inventory item anywhere on it; it follows the pointer from that grab point. On drop, it snaps to the grid cell. No teleport to origin.
“Behaviors and manual Set Position fight. Pick one owner of position per state.”
For polished inventory UX, add a small Tween on drop to the snapped cell — the item glides into place instead of popping.