Class UITKDragObject
UI Toolkit drag object. Displays a dragged icon that follows the cursor and carries the identity of whatever the drag was started from until something drops or cancels it.
public class UITKDragObject : UITKControl
- Inheritance
-
ObjectComponentBehaviourMonoBehaviourUITKDragObject
- Inherited Members
-
MonoBehaviour.IsInvoking()MonoBehaviour.CancelInvoke()MonoBehaviour.StopCoroutine(Coroutine)MonoBehaviour.StopAllCoroutines()MonoBehaviour.destroyCancellationTokenMonoBehaviour.useGUILayoutMonoBehaviour.didStartMonoBehaviour.didAwakeMonoBehaviour.runInEditModeBehaviour.enabledBehaviour.isActiveAndEnabledComponent.GetComponent<T>()Component.TryGetComponent<T>(out T)Component.GetComponentInChildren<T>()Component.GetComponentsInChildren<T>()Component.GetComponentInParent<T>()Component.GetComponentsInParent<T>()Component.GetComponents<T>()Component.GetComponentIndex()Component.CompareTag(TagHandle)Component.transformComponent.transformHandleComponent.gameObjectComponent.tagObject.GetEntityId()Object.GetInstanceID()Object.GetHashCode()Object.InstantiateAsync<T>(T)Object.InstantiateAsync<T>(T, Transform)Object.InstantiateAsync<T>(T, Vector3, Quaternion)Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion, Transform)Object.Instantiate(Object)Object.Instantiate(Object, Scene)Object.Instantiate<T>(T, InstantiateParameters)Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)Object.Instantiate(Object, Transform)Object.Instantiate<T>(T)Object.Instantiate<T>(T, Vector3, Quaternion)Object.Instantiate<T>(T, Vector3, Quaternion, Transform)Object.Instantiate<T>(T, Transform)Object.Destroy(Object)Object.DestroyImmediate(Object)Object.DontDestroyOnLoad(Object)Object.DestroyObject(Object)Object.FindObjectsOfType<T>()Object.FindObjectsByType<T>(FindObjectsSortMode)Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)Object.FindObjectOfType<T>()Object.FindFirstObjectByType<T>()Object.FindAnyObjectByType<T>()Object.FindFirstObjectByType<T>(FindObjectsInactive)Object.FindAnyObjectByType<T>(FindObjectsInactive)Object.FindObjectsByType<T>()Object.FindObjectsByType<T>(FindObjectsInactive)Object.ToString()Object.nameObject.hideFlags
Remarks
THE DRAG IS NOT AUTHORITATIVE AND MUST NEVER BE TREATED AS IF IT WERE. What it holds is a record of what the player picked up and where they picked it up from, taken at the moment they clicked. The containers underneath it are replicated from the server and can change at any point during the drag — a loot broadcast, another panel's swap echo, a scene handover — so by the time the player releases, the slot named in ReferenceID may hold a completely different item. Submitting the slot index alone at that point moves the wrong item, and the player watches something they never touched go somewhere they never put it.
The fix is identity, not optimism: SetItemReference(Sprite, int, ReferenceButtonType, Item) records which item the drag started from, and MatchesSource(Item) re-checks that the source slot still holds it before the drop is allowed to submit anything. A drag that no longer matches is cancelled rather than guessed at.
The payload is also cleared on every teardown path — Hide(bool) (which covers
Escape via UIManager.CloseNext and quit-to-login via Hide(false)),
OnQuitToLogin(), and NotifySlotChanged(ReferenceButtonType, int, Item) from the panels — because a
payload that survives its own panel is a drag the player cannot see and cannot cancel, and
the next click anywhere completes it.
Fields
DropDistance
Maximum distance for drop raycast.
public float DropDistance
Field Value
LayerMask
Layer mask used for raycasting when dropping items.
public LayerMask LayerMask
Field Value
- LayerMask
NULL_ITEM_ID
Constant representing "no item identity" for ItemID.
public const long NULL_ITEM_ID = 0
Field Value
Remarks
Zero rather than -1 because Item.ID defaults to 0 for the display-only
constructor, so an item that never received a server-issued ID is indistinguishable
from no item at all — and must be treated as such rather than matching everything.
NULL_REFERENCE_ID
Constant representing a null reference ID for drag objects.
public const long NULL_REFERENCE_ID = -1
Field Value
ReferenceID
The reference ID associated with the dragged object.
public long ReferenceID
Field Value
Remarks
A container slot index for item drags, a database ID for ability and hotkey drags. Which of the two it is depends entirely on Type.
Type
The type of reference button (e.g., inventory, skill, etc.).
public ReferenceButtonType Type
Field Value
Properties
HasItemIdentity
True when this drag was seeded from a container item and therefore carries an identity that a drop can validate against.
public bool HasItemIdentity { get; }
Property Value
Remarks
Not every drag source has one: ability and hotkey drags carry a database ID in
ReferenceID rather than a slot index, and have no item behind them.
An item whose ID is still NULL_ITEM_ID also does not get one,
because zero is the default and would otherwise match every other unsaved item.
IconSprite
The sprite currently displayed by the drag object, or null when inactive.
public Sprite IconSprite { get; }
Property Value
- Sprite
IsDragging
True while a drag is actually carrying something.
public bool IsDragging { get; }
Property Value
Remarks
Panels used to test Visible, which is a statement about the document rather
than about the payload: a panel shown with no reference in it reads as an active drag
and the next click "completes" a drag that never started.
ItemID
Instance ID of the item this drag was started from, or NULL_ITEM_ID when the drag carries no item identity.
public long ItemID { get; }
Property Value
Remarks
ReferenceID alone is a container slot index, and a slot index is only meaningful for as long as the container does not change underneath the drag. The server can write to that slot at any moment — a loot broadcast, a queued swap echo, a trade — and the drop would then submit the slot the player picked, holding an item they never picked up. Recording which item the drag actually started from is what makes that detectable at drop time.
ItemVersion
Version of the item this drag was started from, paired with ItemID.
public long ItemVersion { get; }
Property Value
Remarks
Client-side items are currently constructed without a version (it stays 0), so this contributes nothing today. It is carried and compared anyway so that the drop-time validation starts rejecting stale drags for free the moment the server begins sending a real version, rather than needing this code to be revisited.
Layer
Draw order tier for this panel. See UITKPanelLayer.
protected override UITKPanelLayer Layer { get; }
Property Value
Methods
Clear()
Clears the drag object state, hides it, and resets reference data.
public void Clear()
Hide(bool)
Hides the drag overlay and drops whatever it was carrying.
public override void Hide(bool overrideIsAlwaysOpen)
Parameters
overrideIsAlwaysOpenboolWhen true, the call is a no-op.
Remarks
Hide(bool) rather than Hide(), because Hide() is only one of the
routes here. Escape arrives through UIManager.CloseNext and quit-to-login
through Hide(false); overriding the parameterless form would miss the second and
leave a payload armed on the login screen, ready to complete itself against whatever
character logs in next.
MatchesSource(Item)
Reports whether item is still the item this drag was started from.
public bool MatchesSource(Item item)
Parameters
itemItemThe item currently occupying the source slot, or null if empty.
Returns
- bool
True when the drop may proceed.
Remarks
Call this at drop time against a fresh read of the source slot, never against the value the drag was seeded with. When the drag carries no identity the best that can be said is "the slot is still occupied", which is what an empty item fails and anything else passes.
NotifySlotChanged(ReferenceButtonType, int, Item)
Cancels the drag if a container write has invalidated its source slot.
public void NotifySlotChanged(ReferenceButtonType type, int slotIndex, Item item)
Parameters
typeReferenceButtonTypeContainer the write landed in.
slotIndexintSlot the write landed in.
itemItemThe item now in that slot, or null if it was emptied.
Remarks
Called by the item panels from their slot-updated handlers. This is the half of the lifecycle a drop-time check cannot cover on its own: without it the icon keeps following the cursor while the thing it represents has already gone, and the player is aiming a drop they are about to be told is invalid. Cancelling as it happens is both more honest and much easier to understand.
OnAfterShow()
Re-applies the drag icon on every show, including the first one.
protected override void OnAfterShow()
Remarks
OnAfterStarting alone is not enough. On the very first open hasStarted is
still false, so ReinitializeIfTreeReplaced returns before re-running it, and the
icon written before Show is lost with the discarded tree.
OnAfterStarting()
Re-applies the drag icon after the visual tree has been rebuilt.
protected override void OnAfterStarting()
Remarks
Per THE CONTRACT: UIDocument clones the UXML afresh on every enable, so the
element SetReference(Sprite, long, ReferenceButtonType) wrote the icon into is discarded the moment the
panel is shown. Without this the very first drag of a session is invisible — the
classic symptom — and every drag after a hide/show is too.
OnDestroying()
Drops the payload when the overlay is destroyed.
public override void OnDestroying()
OnQuitToLogin()
Drops the payload when the client returns to the login screen.
public override void OnQuitToLogin()
Remarks
Belt and braces: CloseOnQuitToMenu is set on this panel in the scene, so the
base class already routes quit-to-login through Hide(false). That is a scene
setting an editor can change, and a drag surviving into the next session is not
something that should depend on one.
OnStarting()
Resolves cached elements and prepares the drag icon for absolute positioning.
public override void OnStarting()
OnTick()
Per-frame update for the drag object. Handles drag visuals and drop logic.
protected override void OnTick()
Remarks
An OnTick override rather than a private Update. Unity binds the
most-derived Update only, so declaring one here silently replaced
UITKControl's — taking PollLoseFocus with it — which is the exact
failure that method's own comment warns about.
SetItemReference(Sprite, int, ReferenceButtonType, Item)
Sets the reference data for a drag started from a container slot, recording which item it was started from so the drop can re-validate it.
public void SetItemReference(Sprite icon, int slotIndex, ReferenceButtonType type, Item item)
Parameters
iconSpriteSprite to display while dragging.
slotIndexintSlot index within the source container.
typeReferenceButtonTypeWhich container the slot belongs to.
itemItemThe item in that slot at the moment the drag began.
SetReference(Sprite, long, ReferenceButtonType)
Sets the reference data for a drag that carries no item identity.
public void SetReference(Sprite icon, long referenceID, ReferenceButtonType type)
Parameters
iconSpriteSprite to display while dragging.
referenceIDlongReference ID for the dragged object.
typeReferenceButtonTypeType of reference button.
Remarks
For ability and hotkey drags, whose referenceID is a database ID
rather than a container slot and which therefore have nothing to re-validate against.
Item panels must use SetItemReference(Sprite, int, ReferenceButtonType, Item) instead.