Back to API Reference
Class

UniTextBase

abstract
Implements:IPointerDownHandlerIPointerUpHandlerIPointerEnterHandlerIPointerExitHandlerIPointerMoveHandler

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

Implements Unity 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 OrderedEvent BeforeGenerateMesh{ get }

Runs after glyph positioning and before mesh generation.

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 int CodepointCount{ get }

Number of codepoints in the rendered text (markup resolved). 0 before the first rebuild. This is the codepoint space shared by RenderedCodepoints, FindAll results, highlight-layer ranges and the range-geometry queries.

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.

public float CurrentFontSize{ get }

Gets the current effective font size (accounts for auto-sizing).

public string Text{ get; set }

Gets or sets the serialized source text. The getter returns the serialized field as-is and has no side effects — use RenderedText to observe what is actually being rendered when an override (SetText buffer or TextResolver) is active.

public Nullable<Rect> VisibleWindow{ get; set }

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 string Language{ get; set }

BCP 47 language tag for this text (e.g. zh-Hans, ja, en-US). Picks the correct font variant for the script and enables the OpenType locl feature. Per-range overrides via <lang=...>...</lang> take priority.

public Color color{ get; set }
public bool IsWorldSpace{ get }

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 bool IsVisible{ get; set }

Whether the text is currently drawn and hit-testable. Setting this is equivalent to calling Show () or Hide ().

public int GlyphCount{ get }

Gets the total number of glyphs.

public static bool UseParallel{ get; set }

Gets or sets whether parallel processing is enabled for multiple components.

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.

public float PreferredHeight{ get }

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.

public string GetRangeText()

Copies one validated rendered-codepoint range into a stable UTF-16 string. This is the shared representation used by range actions and external export adapters.

public int FindAll()

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()

Sets text content from a char array without allocating a string. Ideal for frequently updated text (timers, scores, etc.).

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(string source)

Sets the text to render without writing to the serialized text field. Convenience overload equivalent to SetText(source.AsMemory()). The change does not mark the scene or prefab as dirty.

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 SetAppearanceDirty()

Rebuilds presentation data from cached glyph positions without reporting glyph movement.

public void SetDirty()

Marks the specified pipeline stages dirty, conservatively assuming a mesh rebuild may move glyph faces.

public void SetDirty()

Marks pipeline work dirty and declares the observable outputs that may change when it commits.

public override void SetAllDirty()

Ignores Unity's aggregate Graphic invalidation; use SetDirty.

public override void SetVerticesDirty()

Ignores Unity's Graphic mesh queue; use SetDirty.

public override void SetMaterialDirty()

Ignores Unity's Graphic material queue unless a rendering backend overrides it.

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.

protected override void OnEnable()
protected virtual void Update()
protected override void OnDisable()
protected override void OnDestroy()
protected virtual void Sub()
protected virtual void UnSub()
protected void DeInit()
protected override void OnRectTransformDimensionsChange()
protected override void OnTransformParentChanged()
public override void Rebuild()
protected override void UpdateMaterial()
protected virtual bool ValidateAndInitialize()
protected abstract void UpdateRendering()

Applies generated mesh data to the rendering backend (CanvasRenderer or MeshRenderer sub-meshes).

protected abstract void ClearAllRenderers()

Clears all sub-mesh renderers (without destroying GameObjects).

protected abstract void ApplyVisibility()

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.

protected virtual void OnSetDirty()

Called after SetDirty. Override to trigger Canvas layout rebuild.

protected virtual void OnDeInit()

Called during DeInit for subclass-specific cleanup (e.g., stencil materials).

public void Show()

Re-shows text previously hidden with Hide. Reuses the already-built layout and mesh, so it is allocation-free and instant — no re-parse, shaping, layout or mesh rebuild. No-op if already visible.

public void Hide()

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 override bool Raycast()
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.

public void GetRangeBounds()

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.

public T GetModifier()

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

public bool TryGetModifier()

Try-get form of GetModifier<T>.

public bool TryGetModifier()

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 int GetModifiers(bool includeChildren)

Collects every modifier of type T into results (cleared first) and returns the count. Same search scope as GetModifier<T>.

public bool HasModifier()

Returns true if any style on this component has a modifier of type T.

public bool HasModifier()

Returns true if any style on this component has a modifier assignable to modifierType.

public bool TryGetStyle()

Finds the first style whose modifier is of type T.

public bool TryGetStyle()

Finds the first style whose modifier is assignable to modifierType.

public bool TryGetWholeTextStyle()

Finds the first whole-text style (range..) whose modifier is of type T.

public bool TryGetWholeTextStyle()

Finds the first whole-text style whose modifier is assignable to modifierType.

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.

public static bool IsWholeTextStyle()

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.

public static bool IsWholeTextSource()

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 void SetWholeText()

Adds or updates a whole-text style of modifier type T. If an existing local whole-text style exists, its parameter is updated in place; otherwise a new style is added to Styles.

public void SetWholeText()

Adds or updates a whole-text style for modifierType, creating a new modifier via factory when none is found locally.

public bool ClearWholeText()

Removes the first local whole-text style whose modifier is of type T. Returns true if a style was removed.

public bool ClearWholeText()

Removes the first local whole-text style whose modifier is assignable to modifierType.

public bool ToggleWholeText()

Inverts the presence of a whole-text style of type T. Adds the style with parameter when absent, removes it when present. Returns true if the style is present after the call.

public bool ToggleWholeText()

Inverts the presence of a whole-text style for modifierType, creating a new modifier via factory when adding.

public string GetWholeTextParameter()

Returns the parameter of the first whole-text style of type T, or null.

public string GetWholeTextParameter()

Returns the parameter of the first whole-text style of modifierType, or null.

public Style EnsureStyleFor()

Ensures the component has a Style whose modifier is of type T and whose rule covers rule.

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.

protected virtual void PrepareForParallel()
protected void EnsureFirstPassComplete()

Ensures the first pass (parsing, BiDi, shaping) has run. No-op in the normal pipeline (Phase 1 already ran). Enables LayoutRebuilder.ForceRebuildLayoutImmediate to work outside the pipeline.

protected override void OnDidApplyAnimationProperties()
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.

public int HitTestCaret()

Caret hit test that also reports the affinity bit. Affinity matters at soft-wrap boundaries: a codepoint shared by two lines may render at the right edge of the previous line (upstream) or the left edge of the next line (downstream).

public bool IsOverText()

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.

protected abstract Camera ResolveEventCamera()

Resolves the camera to use for screen-to-local conversion based on the event source.

public Vector2 MeasureText()

Measures the size text occupies under the given constraints and setting overrides — the displayed text, layout and mesh are left untouched.

protected void EnsureLayoutComputed()

Main layout pass. Computes the "preferred" state — cachedPreferredHeight and an initial cachedEffectiveFontSize — for the current rect width. Cached by width only: result is independent of rect.height.

protected void EnsureLayoutFit()

Full layout: main pass then, if needed, shrinks cachedEffectiveFontSize under the current rect.height. Main-pass state comes from the width cache; second pass is cached by rect.height so repeat calls within a frame are free.

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.

public int CountUnits()

How many units of unit granularity the text holds.

public int CountUnits()

How many units of unit granularity range holds. A unit the range only partly covers counts as one.

public bool TryGetLabeled()

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> sourceText
protected float fontSize

Gets or sets the base font size in points.

protected bool wordWrap

Gets or sets whether word wrapping is enabled.

protected bool autoSize

Gets or sets whether automatic font sizing is enabled.

protected float minFontSize

Gets or sets the minimum font size for auto-sizing.

protected float maxFontSize

Gets or sets the maximum font size for auto-sizing.

protected TextProcessor textProcessor
protected UniTextMeshGenerator meshGenerator
protected UniTextBuffers buffers
protected List<UniTextRenderData> renderData
public CachedTransformData cachedTransformData

Cached transform data captured before parallel processing.

public static const int RangeInteractionEventOrder

Built-in range-routing order; lower values intercept it.

public static const int ComponentDefaultEventOrder

Built-in selection/editing order; default subscribers run first.

protected float cachedEffectiveFontSize

Cached effective font size after auto-sizing. Zero means layout has not been computed; consumers fall back to maxFontSize/fontSize as appropriate.

protected float cachedPreferredHeight

Cached preferred height — what the text wants at its unconstrained (main-pass) size. Not updated by the second pass: parent layout groups read this as "desired height", which must stay stable even when the rect is smaller than desired.

public Action Rebuilding

Occurs when text is about to be rebuilt.

public Action RectHeightChanged

Occurs when the RectTransform height has changed.

public Action<UniTextDirty> DirtyFlagsChanged

Occurs when dirty flags have changed, indicating what needs rebuilding.

public Action FrameUpdated

Occurs once per Unity frame from Update. Per-frame consumers subscribe here instead of being driven by hard-coded calls inside Update.

public Action LayoutCommitted

Occurs 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> Committed

Occurs after this component commits a processing pass and identifies which observable outputs changed.

public Action Animated

Occurs 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> TextClicked

Occurs 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> TextLongPressProgress

Occurs 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> PointerLongPressProgress

Pointer-aware long-press progress carrying contact identity and coordinates. TextLongPressProgress remains the hit-only compatibility projection.

public Action<TextHitResult> HoverChanged

Occurs when the hover position has changed. Fires with None when the pointer leaves the text entirely. Notification only.

public Action<TextPointerEvent> PointerReleased

Occurs when the primary button has been released, paired with PointerPressed. Touch gesture recognisers resolve tap / long-press release here.

public Action<TextPointerEvent> PointerEntered

Occurs 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> PointerExited
public Action<TextPointerEvent> PointerMoved

Occurs for pointer movement over this event surface and carries an exact pointer identity. Unlike HoverChanged, it is not limited to mouse-style semantic hover.