UniTextBase
Shared base for UniText components — handles text processing (Unicode, BiDi, shaping, line breaking, modifiers, emoji, font fallback, variable fonts). Concrete subclasses supply the rendering backend: UniText (Canvas) and UniTextWorld (world-space).
Remarks
EventSystem interfaces on the base class so both UniText (driven by GraphicRaycaster) and UniTextWorld (driven by PhysicsRaycaster/Physics2DRaycaster with a collider) receive the same events through the same code path. Event surface. TextClicked — single-tap activation. Consumable: setting Consumed suppresses propagation of the Unity click to the parent UI hierarchy. Multi-tap detection (double = word, triple = line) is the consumer's responsibility — the host emits one event per click without aggregating. ContextRequested — unified context-menu request. Triggered by right-click on desktop or long-press on touch / pen (matches HTML contextmenu, WinUI ContextRequested, SwiftUI.contextMenu). Consumable. TextLongPressProgress — fires every frame while a primary press from a touch / pen pointer is held in place, with progress in [0, 1]. Notification only. Mouse holds do not emit progress. HoverChanged — hover position changed; None when the pointer leaves. Notification only. The base class deliberately does NOT implement the uGUI drag interfaces — a plain label must never capture drags from an enclosing ScrollRect. Drag-to-select lives on UniTextSelectable, which implements the drag handlers on the same GameObject and applies the touch-scroll-vs-select policy. Emitted TextPointerEvent instances are REUSED across emissions — consumers must not retain them beyond the callback.Derived Types(2)
Types that inherit from UniTextBase.
Nested Types
public UniTextDirty CurrentDirtyFlags{ get }Gets the current dirty flags indicating what needs rebuilding.
public TextProcessor TextProcessor{ get }Gets the text processor instance handling shaping and layout.
public UniTextMeshGenerator MeshGenerator{ get }Gets the mesh generator instance.
public UniTextFontProvider FontProvider{ get }Gets the font provider managing font assets and fallbacks.
public UniTextBuffers Buffers{ get }Gets the buffer container for text processing.
public ReadOnlyMemory<char> RawText{ get }The runtime source text — the last value assigned via Text or any SetText overload, before any resolver substitution. Zero-alloc.
public ReadOnlyMemory<char> ResolvedText{ get }Gets the substitute produced by the attached TextResolver on the last rebuild, or an empty memory when no resolver is attached or TryResolve returned. Zero-alloc. Test TextOverride for Resolver to know if this value is in use.
public ReadOnlyMemory<char> RenderedText{ get }Gets the text actually fed into the parsing / shaping / layout pipeline: the resolver's output if one is active, otherwise RawText. Zero-alloc. Still contains markup; for the markup-stripped form use CleanText.
public ReadOnlySpan<char> CleanText{ get }Gets RenderedText with parsed markup removed. Zero-alloc. The backing buffer is pooled and may be rewritten on the next parse — do not store the span; call new string(span) if you need a stable string.
public ReadOnlySpan<int> RenderedCodepoints{ get }The rendered text as Unicode codepoints — the codepoint space highlight layers and range geometry index into. Zero-alloc. The backing buffer is pooled and rewritten on the next rebuild — do not store the span. For the UTF-16 form use CleanText.
public TextOverrideSource TextOverride{ get }Combination of flags describing which runtime source(s) are currently overriding the serialized Text. Flags may combine — for example, SetText | Resolver when a SetText buffer feeds an attached resolver that further substitutes the text.
public IUniTextResolver TextResolver{ get; set }Gets or sets a resolver that may override the source text before parsing without modifying the serialized text field. Useful for editor-time localization preview and runtime text-binding without dirtying scenes or prefabs. See IUniTextResolver for the contract.
public Vector2 ResultSize{ get }Gets the computed size of the rendered text.
public ReadOnlySpan<PositionedGlyph> ResultGlyphs{ get }Gets the positioned glyphs after processing.
public UniTextFont PrimaryFont{ get }Gets the effective primary font: the explicit Font if set, otherwise PrimaryFont from FontStack.
Local-space window that bounds mesh emission: paragraphs fully outside it produce no quads. Layout, selection, caret and hit-testing are unaffected — only rendering is windowed. renders everything. Canvas components feed it from the mask clip rect automatically; set it explicitly for custom virtualized scrollers, in this RectTransform's local space.
public Color color{ get; set }Whether this text renders in world space (a scene mesh) rather than in a Canvas. Consumers that adapt to render space query this instead of testing for a concrete component type; UniTextWorld overrides it to.
public RectTransform RenderRoot{ get }Transform under which this component parents its generated render children (glyph sub-meshes, inline media). Main thread only — the Canvas backend lazily creates a hidden container.
public OrderedValueEvent<TextPointerEvent> ContextRequested{ get }Occurs when the user has requested a context menu. Triggered by either the secondary pointer button (right-click on desktop) or by holding a touch / pen press in place past LongPressDuration. Mirrors the HTML contextmenu / WinUI ContextRequested / SwiftUI.contextMenu pattern of one event with multiple platform-appropriate triggers. Fires anywhere on the component's raycast surface (a field's menu must open over its empty area too) — Hit is a no-hit result off-glyph. Consumable. Callbacks run by ascending order and all receive the event even after it is consumed. The range router uses RangeInteractionEventOrder, ordinary subscriptions default to zero, and selection / editing defaults use ComponentDefaultEventOrder.
public OrderedValueEvent<TextPointerEvent> PointerPressed{ get }Occurs when the primary button has been pressed, before any click resolution. The press anchor for gesture pipelines: caret placement and focus acquisition happen here (click events fire only after release). Resolve the caret cluster from ScreenPosition via HitTestCaret; the bundled Hit is the bounding-box hit. Callbacks run by ascending order and all receive the event even after it is consumed. The range router uses RangeInteractionEventOrder, ordinary subscriptions default to zero, and selection / editing defaults use ComponentDefaultEventOrder.
public TextHitResult LastHoverResult{ get }Last hover hit test result. Tracked only while HoverChanged has subscribers — without them the per-move hit test is skipped and this stays None.
Height the text content needs inside the padded inner rect (accounts for auto-sizing). Does not include vertical Padding — this is the content-box height, matching CSS height with box-sizing: content-box. The ILayoutElement contract adds vertical padding so ContentSizeFitter sizes the outer RectTransform to fit content + padding.
public TextRange TextSpan{ get }Codepoint span of the whole processed text — the rendered text after parsing, which is what every structure and range API addresses.
public TextSnapshot CaptureTextSnapshot()Captures immutable rendered text and its range-coordinate revision. The component must have completed at least one parse after its current style graph was attached.
Finds every occurrence of query in the rendered text, writing one codepoint range per match into results (left to right, non-overlapping). Returns the number of matches written; stops early when results is full. Ranges feed MutableRangeSource and GetRangeBounds directly. Allocation-free for queries up to 64 UTF-16 chars. Main thread.
public void SetText(ReadOnlyMemory<char> source)Sets the text to render without writing to the serialized text field. The change is visible at runtime and in edit mode without marking the scene or prefab as dirty — suitable for editor-time preview (localization) or transient runtime substitution.
public void SetText(StringBuilder source)Sets the text to render from a StringBuilder without writing to the serialized text field and without allocating a string. The contents are copied into a pooled internal buffer, so the supplied StringBuilder may be mutated freely after the call.
public void SetText(ReadOnlySpan<char> source)Sets the text to render from a character span without writing to the serialized text field and without allocating a string. The span is copied into a pooled internal buffer, so its backing storage may be reused or released immediately after the call — making this the safe bridge from a pool-rented builder such as ZString's Utf16ValueStringBuilder.AsSpan().
public Rect GetPaddedRect()The rect with Padding applied: origin shifted by (Left, Bottom), size shrunk by (Left+Right, Bottom+Top), clamped to non-negative. Main-thread only.
public void AddRule(ParseRule rule)Adds a standalone parse rule (one that operates without a modifier, e.g. <noparse>). The rule must report IsStandalone as.
public bool RemoveRule(ParseRule rule)Removes a standalone rule previously added via AddRule.
Applies the current RenderSuppressed state to the rendering backend. Must only toggle drawing — cull for Canvas, batch membership (degenerate indices) for world — never tear down or rebuild, so the user Show/Hide and the scene-visibility eye share one allocation-free, non-structural path.
Hides the text while keeping its built layout, mesh and pooled buffers intact: stops drawing and pointer hit-testing without tearing down the pipeline. Prefer this over disabling the GameObject/component or assigning empty text for text shown and hidden repeatedly (pooled lists, tooltips, HUD) — those force a full pipeline rebuild on every re-show, whereas Show after Hide is free. No-op if already hidden.
public void CollectRangeEntries(int startCluster, int endCluster, PooledList<LineRangeEntry> output)Collects per-line geometric runs of positioned glyphs whose clusters fall inside [startCluster, endCluster). Output bounds are in mesh-local coordinates with X clamped to each line's measured extent. One LineRangeEntry is emitted per contiguous run within a line — multiple entries per line are possible if the matched clusters are non-contiguous in visual order.
Gets bounding rectangles for a cluster range. One Rect per contiguous run of glyphs within a line that falls inside [startCluster, endCluster). Trailing whitespace at line ends is excluded (CSS Text §4.1.3). Empty wrapped lines whose break codepoint lies inside the range receive a synthetic narrow rect for caret/selection rendering. Wrapper over CollectRangeBounds in LineBox mode.
Returns the first modifier of type T attached to this component — local Styles first, then StylePresets runtime copies, including CompositeModifier children — or if none.
public BaseModifier GetModifier()Returns the first modifier assignable to modifierType, or. Same search scope as GetModifier<T>.
Same lookup as GetModifier<T>, also returning the Style that owns the found modifier (for a match inside a CompositeModifier — the composite's style).
public IEnumerable<Style> GetStylesOfType()Enumerates every style whose modifier is of type T, local first.
public IEnumerable<Style> GetStylesOfType()Enumerates every style whose modifier is assignable to modifierType, local first.
True when the style targets the entire text — either it has no source (the canonical no-constraint form created by WholeText) or it carries a FixedRangeSource whose single entry resolves to the full range.
True only for a FixedRangeSource instance that covers the full text. Use IsWholeTextStyle when checking a style — that variant also accepts the canonical source-less form.
public Style EnsureStyleFor()Non-generic overload of EnsureStyleFor<T> that uses an externally-constructed modifier when the component does not already have one of the same type.
public TextHitResult HitTestRange(Vector2 localPosition, float maxDistance)Range hit test: returns the glyph (and its cluster) under the point. Inclusive of the whole glyph bounding box — clicks anywhere on glyph N return cluster N. Use for entity queries: links, hashtags, mentions, hover-style ranges where left-half vs. right-half of a glyph is irrelevant. Not for caret placement — use HitTestCaret for that, since caret semantics need the edge-snap (left half → before-glyph, right half → after-glyph).
public TextHitResult HitTestRange()Range hit test from screen coordinates. Overload around HitTestRange that performs the screen-to-local conversion.
public int HitTestCaret(Vector2 screenPosition, Camera eventCamera)Caret hit test: returns the codepoint cluster where a caret should be placed for the given screen point. Snaps to the nearest glyph edge on the line determined by the point's vertical coordinate — left half of glyph N → cluster N (caret before the glyph), right half → cluster N+1 (caret after the glyph). Use for caret placement, drag-extend selection, click-to-position. Not for entity detection — clicks at the right edge of a link's last glyph would snap past the link's range; use HitTestRange for that.
Whether the point lies over laid-out text: inside a line's vertical band and within that line's content extent — the web line-box model (gaps between words on a line count as text, the empty area past the line's end does not). Drives hover affordance (I-beam cursor). For caret placement use HitTestCaret, which snaps from any distance instead of rejecting.
public Vector2 MeasureText()Measures the size text occupies under the given constraints and setting overrides — the displayed text, layout and mesh are left untouched.
public TextUnitSequence Units()The text's units of unit granularity, in logical order. Enumerating allocates nothing; nothing is computed until it is.
public TextUnitSequence Units()The units of unit granularity inside range, in logical order, each clipped to the range. Out-of-bounds parts of the range are dropped.
Codepoint span of the range the author anchored with #label, whatever modifier's tag carries it — the whole-text counterpart of a modifier's own WhereLabel query, for a caller that knows the name but not the owner. The first such range in text order answers when a name was used more than once.
public TextRange UnitAt()The unit of unit granularity holding codepointIndex, or an empty range at that index when the text does not reach it.
protected ReadOnlyMemory<char> sourceTextprotected TextProcessor textProcessorprotected UniTextMeshGenerator meshGeneratorprotected UniTextBuffers buffersprotected List<UniTextRenderData> renderDatapublic CachedTransformData cachedTransformDataCached transform data captured before parallel processing.
public Action RebuildingOccurs when text is about to be rebuilt.
public Action RectHeightChangedOccurs when the RectTransform height has changed.
public Action<UniTextDirty> DirtyFlagsChangedOccurs when dirty flags have changed, indicating what needs rebuilding.
public Action FrameUpdatedOccurs once per Unity frame from Update. Per-frame consumers subscribe here instead of being driven by hard-coded calls inside Update.
public Action LayoutCommittedOccurs when THIS component's mesh has been applied in a processing sweep (main thread, layout and glyph geometry are final for the frame). Fires only when this component actually reprocessed — consumers reacting to layout changes (coordinate maps, caret geometry, auxiliary geometry, overlay positioning) subscribe here and never pay for other components' updates.
public Action<UniTextCommitChanges> CommittedOccurs after this component commits a processing pass and identifies which observable outputs changed.
public Action AnimatedOccurs after Unity's Animator applied animated property values to this component. The Animator writes serialized fields directly, bypassing the property setters that raise UniTextDirty, so nothing invalidates on its own — attach a UniTextAnimationBridge with the handlers for the fields you animate, or subscribe here and run your own diff, calling SetDirty with the matching flags.
public Action<TextPointerEvent> TextClickedOccurs when a primary-button click has been confirmed anywhere on this component's raycast surface — Hit is a no-hit result when no glyph is under the pointer. Subscribers set Consumed to suppress propagation of the underlying Unity click to the parent UI hierarchy.
public Action<TextHitResult,float> TextLongPressProgressOccurs every frame while a touch / pen pointer is being held in place after the initial press, with progress climbing from 0 to 1 over LongPressDuration. Stops once the press resolves into a ContextRequested event or is cancelled by movement / release. Mouse holds do not emit. Notification only.
public Action<TextPointerEvent,float> PointerLongPressProgressPointer-aware long-press progress carrying contact identity and coordinates. TextLongPressProgress remains the hit-only compatibility projection.
public Action<TextHitResult> HoverChangedOccurs when the hover position has changed. Fires with None when the pointer leaves the text entirely. Notification only.
public Action<TextPointerEvent> PointerReleasedOccurs when the primary button has been released, paired with PointerPressed. Touch gesture recognisers resolve tap / long-press release here.
public Action<TextPointerEvent> PointerEnteredOccurs when this surface has become the topmost raycast target under the pointer (paired with PointerExited when it ceases to be). Tracks the actual hovered element, not mere rect containment, so an occluding child / overlapping graphic with a raycast target suppresses it. Hit is not computed — consumers needing a hit re-test from the position.
public Action<TextPointerEvent> PointerExitedpublic Action<TextPointerEvent> PointerMovedOccurs for pointer movement over this event surface and carries an exact pointer identity. Unlike HoverChanged, it is not limited to mouse-style semantic hover.
