Data produced by HCP Unreal
HCP Unreal’s 53 generated capture components and 79 generated event emitters are 1:1 wrappers over HEAT ProtoLib’s own components and events - see ProtoLib’s message reference for what each field means, its unit and its range. This page covers the mechanism around them: how an entity gets registered, when it gets captured, how a component’s data gets populated, and how an event actually reaches HEAT Capture.
Entities
An entity is registered either automatically - AHEATActor registers itself and its owning actor
on BeginPlay, if its own Auto Register property is left on - or explicitly, by calling
RegisterEntity (for a whole actor) or RegisterComponentEntity (for a sub-part of an actor,
such as a turret, that should be its own linked entity) on UHEATCaptureSubsystem. Each gets a
64-bit, Snowflake-style id generated by the plugin itself (41-bit millisecond timestamp since
2024-01-01 UTC, 23-bit per-millisecond sequence) - not an Unreal engine object id.
RegisterEntity (the path AHEATActor itself uses) captures no transform on its own.
Automatic position/rotation/scale synthesis from an owning USceneComponent only happens for
entities registered through RegisterComponentEntity, which takes an explicit TransformSource
and a bCaptureTransform flag (on by default there). A plain AHEATActor gets position data
only if you attach a HEATTransformComponent to it - which is exactly what the plugin’s own
quick-start walkthrough does, and is not optional decoration.
Capture timing
Three independent, cascading gates decide whether a given entity’s given component is captured on a given tick - all must pass:
- Global
UpdateRate(Project Settings, default1.0s) - gates the whole subsystem tick. Below this rate, nothing is built for any entity. - Per-entity update frequency - seconds between captures for that entity specifically,
passed when registering it (
0falls back to the globalUpdateRate). Despite being namedUpdateFrequencyin the API, it is a period in seconds, not a rate in Hz. - Per-component
CaptureFrequencyHz(on each attached generated component, default0) - an actual frequency in Hz this time.0adds no further throttling beyond whatever the entity level already decided; a positive value skips this component on ticks that come sooner than1 / CaptureFrequencyHzsince its own last capture, independent of every other component on the same entity.
A component can also be turned off entirely with its own bCaptureEnabled property, independent
of the timing gates above.
Data binding
Each generated component’s fields can be populated three ways, in this priority order (highest wins when more than one is set):
- Direct properties - set the component’s
UPROPERTYfields directly, in the editor, in a Blueprint, or in C++. CaptureConfig- an optionalUHEATCaptureConfigdata asset assigned to the component, mapping each proto field to a property on a named source component by Unreal reflection, or to a Blueprint-assignable custom getter delegate (one delegate type per proto field type: float, vector, quaternion, transform, bool, int, string, enum).OnProvideData- a Blueprint-assignable delegate on every generated component, fired immediately before that component is captured. Whatever it sets last, wins.
Events
Two kinds of event, both delivered in the next SimulationFrame after they are queued - not
sent as their own separate WebSocket message the way HCP VBS’s events are:
- Tracking events -
EmitTrackingEvent(staticUHEATEventBlueprintLibrary, or an instance method on anyHEATEventEmitterBase-derived component) with one of theTrackingEventTypevalues. - Data events - either a generic
EmitJsonDataEvent(EventName, JsonPayload)for an arbitrary JSON payload, or a typed event from one of the 79 generated emitter components (58 tracking, 21 data), which populate a specificEntityDataEventpayload the same way a capture component populates itsComponent.
Every emitter supports optional rate limiting (bEnableRateLimit, MaxEventsPerSecond, default
off): an event that arrives before the minimum interval has elapsed is dropped, not queued or
delayed.
By default an emitter attached to an actor emits on behalf of that actor’s own registered entity;
EmitterEntity on the component can point it at a different entity instead (for example, a
weapon’s fire event attributed to its parent vehicle rather than the weapon’s own sub-entity).
See the generated headers in Generated/Emitters/ for the full emitter catalogue, and
ProtoLib’s message reference for the TrackingEventType values and
EntityDataEvent payload shapes.