Table of Contents

Class UITKDragObject

Namespace
FishMMO.Client
Assembly
FishMMO.Client.dll

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
Object
Component
Behaviour
MonoBehaviour
UITKDragObject
Inherited Members
MonoBehaviour.IsInvoking()
MonoBehaviour.CancelInvoke()
MonoBehaviour.StopCoroutine(Coroutine)
MonoBehaviour.StopAllCoroutines()
MonoBehaviour.destroyCancellationToken
MonoBehaviour.useGUILayout
MonoBehaviour.didStart
MonoBehaviour.didAwake
MonoBehaviour.runInEditMode
Behaviour.enabled
Behaviour.isActiveAndEnabled
Component.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.transform
Component.transformHandle
Component.gameObject
Component.tag
Object.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.name
Object.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

float

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

long

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

long

ReferenceID

The reference ID associated with the dragged object.

public long ReferenceID

Field Value

long

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

ReferenceButtonType

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

bool

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

bool

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

long

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

long

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

UITKPanelLayer

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

overrideIsAlwaysOpen bool

When 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

item Item

The 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

type ReferenceButtonType

Container the write landed in.

slotIndex int

Slot the write landed in.

item Item

The 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

icon Sprite

Sprite to display while dragging.

slotIndex int

Slot index within the source container.

type ReferenceButtonType

Which container the slot belongs to.

item Item

The 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

icon Sprite

Sprite to display while dragging.

referenceID long

Reference ID for the dragged object.

type ReferenceButtonType

Type 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.