Skip to content

Widget Component and World-Space Widgets

A Widget Component is not Add to Viewport in 3D clothing. It is a component on an actor that owns a widget instance and draws that widget through the world or screen presentation path.

At a glance

Use this for: health bars over enemies, nameplates, in-world terminals, diegetic panels, and actor-attached labels - Lives on: an actor as a WidgetComponent - Creates: one UserWidget instance for that component - Main split: World space can be occluded and lives in 3D; Screen space follows the actor but draws as screen UI - Official docs: Widget Components and UWidgetComponent

The one-minute version

  • A Widget Component lets an actor display a Widget Blueprint from a component. It is part of the actor, not a viewport layer owned by the PlayerController.
  • In World space, the widget is rendered onto a surface in the world. It can be blocked by walls, lit/tinted by rendering settings, scaled in world units, and interacted with by a Widget Interaction Component.
  • In Screen space, the component still follows an actor, but the widget is drawn to the player's screen instead of becoming a real 3D surface.
  • Draw Size is the render target/UI canvas size, not automatically "make text readable from ten meters away." World scale and distance still matter.
  • Draw at Desired Size and constant redraws are convenient but can become expensive when many actors have widgets. Use fixed draw sizes and event updates first.
  • A Widget Component does not replicate the widget. Replicate the actor state, then let each local widget instance display that state.

What it actually creates

A Widget Component is a component class you add to an actor Blueprint. You pick a Widget Class, such as WBP_FloatingHealthBar, and the component creates and manages a widget instance for that actor component.

BP_Enemy
-> WidgetComponent
   Widget Class = WBP_FloatingHealthBar
   Space = World
   Draw Size = 240 x 48
   Pivot = 0.5, 1.0
   Relative Location = 0, 0, 120

At runtime, the relationship is:

Actor instance
-> WidgetComponent instance
-> UserWidget instance owned/displayed by that component
-> widget draws actor state such as name, health, interact text, or icon

That is different from:

PlayerController
-> Create Widget WBP_HUD
-> Add to Viewport

The viewport HUD is one local screen layer for a player. The Widget Component is attached to a world actor, so if there are twelve enemies, there can be twelve component-owned widget instances.

World space vs screen space

The Space setting changes how the component presents the widget:

Space What the player sees Use when Watch out
World A real 3D surface at the component transform. Terminals, diegetic panels, VR UI, occludable labels, actor-attached bars that should feel in the world. Distance, scale, orientation, occlusion, material, and interaction all matter.
Screen A screen-facing widget positioned from the actor/component. Simple floating labels that should stay readable and not be hidden by walls. It can look like a HUD element even though it is still actor-driven.
Add to Viewport A widget in the local player's viewport layer. HUDs, menus, crosshairs, scoreboards, pause screens. It does not follow a world actor unless you project positions yourself.

World space is the more physical option. Screen space is the more readable option. Add to Viewport is the player HUD/menu option.

Draw size, pivot, scale, and desired size

Four settings solve different problems:

Setting Beginner meaning
Draw Size The pixel-like canvas size the widget is rendered into, such as 240 x 48.
Relative Scale How large the component's surface is in the actor/world.
Pivot Which point of the widget sits on the component origin. 0.5, 1.0 means centered bottom.
Draw at Desired Size Resize the render target to the widget's desired layout size. Useful for dynamic panels; avoid as a default for many constantly changing widgets.

If a health bar looks blurry, tiny, or clipped, do not randomly increase every number. Check which problem you actually have:

Text clipped inside the widget
-> increase Draw Size or fix widget layout

Whole widget too small in the world
-> increase component scale or move it closer

Widget origin feels wrong
-> adjust Pivot and Relative Location

Many labels cost too much
-> fixed Draw Size, event-driven updates, visibility distance gates

Updating the widget

The component can create the widget, but it does not know what your actor's health, name, team, or objective text means. You still push data into the widget the same way you would for screen UI.

Common actor-owned setup:

BeginPlay on BP_Enemy
-> Get Widget Component
-> Get User Widget Object
-> Cast to WBP_FloatingHealthBar
-> Store FloatingHealthWidget
-> FloatingHealthWidget.SetSourceActor(Self)
-> bind HealthComponent.OnHealthChanged to FloatingHealthWidget.UpdateHealth
-> FloatingHealthWidget.UpdateHealth(CurrentHealth, MaxHealth)

For reusable widgets, prefer an explicit setup function:

WBP_FloatingHealthBar.Setup(OwnerActor, HealthComponent, DisplayName)

That is clearer than letting the widget search the world or guess its owner.

Manual redraw and update frequency

A Widget Component can redraw automatically, manually, or at a limited redraw interval. Beginners usually only need this rule:

Change gameplay state by event, and redraw world widgets only as often as the visible value needs.

Examples:

UI Good update path
Enemy health bar Update when health changes; hide when full/dead/out of range if desired.
Nameplate Update name/team when PlayerState changes; rotate/facing may update per frame if needed.
Timer panel Update text at a readable interval, often several times per second or once per second.
In-world keypad Redraw on button/input state changes.

The quick path is to leave every floating widget ticking, binding, and redrawing every frame. The concrete cost appears when twenty enemies each run UI layout, casts, bindings, and render-target updates for values that did not change.

Occlusion and facing

World-space widgets behave more like world geometry than viewport HUD:

  • walls can hide them;
  • they can be too small or angled away from the camera;
  • lighting/material settings can affect readability;
  • depth sorting can make overlapping translucent UI confusing;
  • two-sided rendering may be needed for panels seen from both sides.

For enemy labels that should always face the player's camera:

Tick or timer on local presentation path
-> Find look-at rotation from widget location to local camera
-> set widget component world rotation

Keep that as local presentation. The server does not need to rotate every client's nameplate toward that client's camera.

Lifetime and multiplayer

A Widget Component is a component on an actor, so it follows that actor's lifetime. Destroy the actor, and the component/widget go away too. Reusing, respawning, pooling, or changing the actor's state means the widget needs a fresh setup path just like any other component-owned reference.

In multiplayer:

Server:
    owns gameplay state such as Health, TeamId, DisplayName, ObjectiveState
    replicates compact values on actor, PlayerState, or GameState

Each client:
    has local actor copy and local WidgetComponent/user widget
    updates the widget from replicated values or OnRep/apply helpers

Do not replicate the WBP_FloatingHealthBar object as the truth. Widgets are local presentation. Replicate the state they need.

When it fails, and what failure looks like

Symptom Likely cause
Nothing appears Widget Class is unset, component hidden, actor not spawned, draw size is zero/tiny, or the widget is behind/inside geometry.
Widget appears but shows defaults The actor never got Get User Widget Object, cast, setup, or initial refresh.
Text is clipped or blurry Draw Size/layout does not match the content, or the component is scaled/distant in world space.
Widget is visible through walls when it should not be It is Screen space or viewport UI, not World space.
Widget is hidden by walls when it should always show World space is being occluded; use Screen space or viewport projection for that feature.
Every enemy shows the same health Widget reused a stale source reference or read a global player value instead of the owning actor's component.
Performance drops near crowds Too many widgets tick, bind, redraw, or draw at desired size every frame.
Multiplayer clients see stale values Gameplay state was not replicated, or the widget updated only on the server copy.

Debug one actor first: print the actor name, widget component name, returned user widget object, and source data you assign to the widget.

What Widget Components do not do

  • They do not add a widget to the viewport.
  • They do not create gameplay state such as health, score, team, or objective progress.
  • They do not make a widget interactive by themselves; use a Widget Interaction Component or normal viewport input depending on the feature.
  • They do not replicate widgets.
  • They do not automatically face the player's camera.
  • They do not automatically know which actor, HealthComponent, or PlayerState they should display unless you wire that reference.
  • They do not make hundreds of constantly redrawn UI surfaces free.

Lookalikes - which one do I want?

Tool Use when Watch out
Widget Component: World space UI should exist as a surface in the 3D world. Occlusion, scale, orientation, redraw cost, and world interaction matter.
Widget Component: Screen space UI should follow an actor but draw on the screen. It may ignore world occlusion expectations.
Add to Viewport / Player Screen The player needs HUD or menu UI. It is local player screen UI, not actor geometry.
Project World Location to Widget Position A viewport HUD should place a marker over a world target. You own off-screen, distance, overlap, and split-screen rules.
TextRender / mesh labels You only need simple world text without UMG layout. Less flexible than UMG widgets.
Niagara or material indicators A marker is visual feedback, not interactive UI. It will not give you buttons, focus, or UMG layout.

Rule of thumb: use Widget Component when the UI belongs to an actor in the world; use viewport widgets when the UI belongs to the player's screen.

Going deeper