Skip to Content
This documentation is provided with the HEAT environment and describes this HEAT instance.

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:

  1. Global UpdateRate (Project Settings, default 1.0 s) - gates the whole subsystem tick. Below this rate, nothing is built for any entity.
  2. Per-entity update frequency - seconds between captures for that entity specifically, passed when registering it (0 falls back to the global UpdateRate). Despite being named UpdateFrequency in the API, it is a period in seconds, not a rate in Hz.
  3. Per-component CaptureFrequencyHz (on each attached generated component, default 0) - an actual frequency in Hz this time. 0 adds no further throttling beyond whatever the entity level already decided; a positive value skips this component on ticks that come sooner than 1 / CaptureFrequencyHz since 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):

  1. Direct properties - set the component’s UPROPERTY fields directly, in the editor, in a Blueprint, or in C++.
  2. CaptureConfig - an optional UHEATCaptureConfig data 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).
  3. 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 (static UHEATEventBlueprintLibrary, or an instance method on any HEATEventEmitterBase-derived component) with one of the TrackingEventType values.
  • 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 specific EntityDataEvent payload the same way a capture component populates its Component.

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.

Opens your browser's print dialog. Choose "Save as PDF" as the destination.