Class UITKTarget
UI Toolkit target frame: two cards side by side. The HOVER card follows the pointer, as the frame always has; the PINNED card holds a character the player chose to track and stays up until they release it, it dies, it despawns or it leaves range. Each card shows its target's name (faction-coloured), a health bar, its faction standing, and strips of the buffs and debuffs the SERVER has chosen to show observers. The overhead 3D label, outline and faction colouring are rendering-agnostic and driven from here rather than from the visual tree.
public class UITKTarget : UITKCharacterControl
- Inheritance
-
ObjectComponentBehaviourMonoBehaviourUITKTarget
- 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
Two cards, one panel. Action combat does not want a sticky target: abilities go where the player aims, and the hover frame is the readout for that. What players asked for is a way to keep ONE opponent's health and debuffs on screen while the pointer sweeps across everyone else in the fight — so the pin is a second card, not a change to the first. Nothing gameplay-authoritative reads either card. The two never show the same character: when the pointer rests on the pinned character the hover card stands down, because two identical cards say nothing that one does not.
Change-driven. TargetController re-raises OnUpdateTarget twenty times a
second for as long as the pointer rests on something, and this panel treated every one of
them as a brand-new target: seven GetComponent calls, two or three string
concatenations, a full reconcile of the buff strip and — worst — a destroy/recreate cycle of
the overhead 3D label, twenty times a second, for a target that had not changed. Everything
that depends only on WHICH target is resolved once, on the change; the update path only
re-reads the values that actually move. The pinned card gets no update event at all, so
its health is re-read from OnTick() — an integer comparison per frame.
Model / view split. The displayed values live in each card's fields; the elements
belong to one visual tree and are rebuilt from those fields in OnAfterShow /
OnAfterStarting. UIDocument re-clones the UXML on every enable, so a frame
that wrote its content before Show() — or cached elements across a hide/show — comes
back blank.
Fields
HealthAttributeID
The health attribute template ID used to identify the target's health resource.
[TemplateReference(typeof(CharacterAttributeTemplate))]
public int HealthAttributeID
Field Value
Properties
Layer
Draw order tier for this panel. See UITKPanelLayer.
protected override UITKPanelLayer Layer { get; }
Property Value
Methods
OnAfterShow()
Called at the end of Show(), against the tree the player will actually see. Override to write content that changes from one opening to the next.
protected override void OnAfterShow()
Remarks
This exists because "set the text, then Show" does not work and fails silently. UnityEngine.UIElements.UIDocument clones the UXML on enable, so a panel that fills in its message, list rows or icon before calling Show() writes into a tree that is thrown away microseconds later, and the player sees whatever the UXML declares — an empty dialog, a blank tooltip, a selector with no rows.
Distinct from OnAfterStarting(), which re-applies state after the tree is rebuilt. This one runs on every show, rebuilt tree or not.
OnAfterStarting()
Re-applies the character once the visual tree exists.
protected override void OnAfterStarting()
Remarks
World entry calls FishMMO.Client.UIManager.SetCharacter(FishMMO.Shared.Core.IPlayerCharacter) for every control at once, and
a control that starts hidden has no visual tree until something shows it — so
OnPostSetCharacter() can run before OnStarting has cached any
elements. Overrides that write into those elements would then dereference null, and
even a null-safe one would leave the panel showing nothing, because the only call
that had data already happened. Running it again here is what makes the two orders
equivalent.
OnDestroying()
Releases the observed-buff subscription and the overhead nameplates.
public override void OnDestroying()
OnPostSetCharacter()
Subscribes to the target controller after the character is set.
public override void OnPostSetCharacter()
OnPreSetCharacter()
Unsubscribes from the target controller before a character is set.
public override void OnPreSetCharacter()
Remarks
Pairs with OnPostSetCharacter() so the two can be run back to back without subscribing twice. That happens whenever this panel's visual tree is rebuilt and its state has to be re-applied — the unsubscribe already existed for the unset path, but re-applying the same character never went through it.
OnPreUnsetCharacter()
Unsubscribes from the target controller and releases both cards.
public override void OnPreUnsetCharacter()
OnQuitToLogin()
Called when the client quits to the login screen. Override to perform cleanup such as stopping coroutines.
public override void OnQuitToLogin()
OnStarting()
Queries both cards' elements and subscribes to the observed-buff push.
public override void OnStarting()
Remarks
Re-runs on every tree rebuild. The pooled icons belong to the tree that was just replaced, so the pool is dropped rather than reused; the static subscription is removed before it is added so rebuilds cannot stack handlers.
OnTick()
Re-reads the pinned card's health and animates both cards' remaining-duration fills.
protected override void OnTick()
Remarks
The pinned card has no update event: the controller only re-reports what the pointer is on. Its health is therefore polled here, and FishMMO.Client.UITKTarget.RefreshHealth(FishMMO.Client.UITKTarget.TargetCard) makes that two integer comparisons per frame until a number actually moves. The buff countdown is local for both cards — the server pushes an observed-buff list only when the SET changes, so the entries carry the seconds remaining at send time and this subtracts the time elapsed since. Skipped entirely when nothing is on screen.
TargetController_OnChangeTarget(Transform)
Frames a newly hovered target in the hover card.
public void TargetController_OnChangeTarget(Transform target)
Parameters
targetTransformThe new target transform.
TargetController_OnClearTarget(Transform)
Releases the hover card when the pointer leaves its target.
public void TargetController_OnClearTarget(Transform lastTarget = null)
Parameters
lastTargetTransformThe previous target transform, if any.
TargetController_OnUpdateTarget(Transform)
Handles a hover update — the same target, re-reported on the controller's poll.
public void TargetController_OnUpdateTarget(Transform target)
Parameters
targetTransformThe target transform.
Remarks
This used to call straight into TargetController_OnChangeTarget(Transform), treating twenty polls a second as twenty target changes. It now only re-reads what moves.