# IPersonBase

<Badge tone="type">UINTERFACE · BlueprintType</Badge> <Badge tone="accent">BlueprintCallable</Badge> <Badge tone="accent">BlueprintNativeEvent</Badge>

```cpp
UINTERFACE(BlueprintType)
class UPersonBase : public UInterface { GENERATED_BODY() };

class AR51SDK_API IPersonBase
{
    GENERATED_BODY()
    // methods: BlueprintCallable, BlueprintNativeEvent
};
```

**Implements:** [`UInterface`](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/CoreUObject/UObject/UInterface) *(Unreal Engine)*

One tracked person. This is what the [`USkeletonConsumer`](/docs/sdk-api/unreal-api/classes/skeletonconsumer) lookup methods return, as [`TScriptInterface<IPersonBase>`](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/CoreUObject/UObject/TScriptInterface). It is implementable in both C++ and Blueprint; every method is a `BlueprintNativeEvent`, so from C++ you call it through the generated `Execute_` thunk (see [Calling convention](#calling-convention)).

:::note[Id semantics]
- **`PersonId`** (`GetId`) — the **mocap system's** per-person id. The key for [`GetPersonByPersonId`](/docs/sdk-api/unreal-api/classes/skeletonconsumer#getpersonbypersonid) and `PersonIdToCharacterBPMap`.
- **`DeviceId`** (`GetDeviceId`) — the associated headset/device id.
- **`EntityId` / `EntityDisplayName`** come from an **external system** and are *not* on `IPersonBase` directly — they live on the [`USkeletonConsumer`](/docs/sdk-api/unreal-api/classes/skeletonconsumer) mapping APIs (`GetPersonByEntityId`, `EntityIdToCharacterBPMap`, …) and are used to choose which character Blueprint to spawn.
- The **active person** is the one whose headset/camera is currently in use ([`USkeletonConsumer::GetActivePerson`](/docs/sdk-api/unreal-api/classes/skeletonconsumer#getactiveperson)). The `OnActivePersonChanged` event passes an **empty string** (`""`) when no skeleton is associated with the headset.
:::

## Method summary

All methods are `BlueprintCallable, BlueprintNativeEvent` and `const`.

| Method | Returns | |
|---|---|---|
| [`GetId`](#getid) | `FString` | <Badge tone="accent">BlueprintNativeEvent</Badge> |
| [`GetDeviceId`](#getdeviceid) | `FString` | <Badge tone="accent">BlueprintNativeEvent</Badge> |
| [`GetCharacter`](#getcharacter) | [`UAR51Character*`](/docs/sdk-api/unreal-api/classes/uar51character) | <Badge tone="accent">BlueprintNativeEvent</Badge> |
| [`GetModel`](#getmodel) | [`AActor*`](https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Engine/GameFramework/AActor) | <Badge tone="accent">BlueprintNativeEvent</Badge> |
| [`GetLastUpdateTime`](#getlastupdatetime) | `float` | <Badge tone="accent">BlueprintNativeEvent</Badge> |
| [`GetTimeFromLastUpdate`](#gettimefromlastupdate) | `float` | <Badge tone="accent">BlueprintNativeEvent</Badge> |
| [`IsTracked`](#istracked) | `bool` | <Badge tone="accent">BlueprintNativeEvent</Badge> |

→ Full descriptions in [Method details](#method-details) below.

## Calling convention

Because every method is a `BlueprintNativeEvent`, **do not call `Obj->GetCharacter()` directly** from C++. Call the static `Execute_` thunk the interface generates, passing the underlying `UObject*`:

<Example inferred>

```cpp
// A TScriptInterface<IPersonBase> comes back from the consumer.
TScriptInterface<IPersonBase> Person = Consumer->GetActivePerson();

if (UObject* Obj = Person.GetObject())   // null when no active person
{
    // BlueprintNativeEvent → call through Execute_:
    UAR51Character* Char = IPersonBase::Execute_GetCharacter(Obj);
    const FString    Id  = IPersonBase::Execute_GetId(Obj);

    if (Char && IPersonBase::Execute_IsTracked(Obj))
    {
        const FVector Head = Char->GetHeadPosition();   // UE world space, cm
    }
}
```

</Example>

In Blueprint the same methods appear as ordinary nodes off a `TScriptInterface<IPersonBase>` (or `Person Base` reference) pin — no `Execute_` wrapper needed.

## Method details

### GetId

<ApiBody kind="method" tags="BlueprintCallable, BlueprintNativeEvent">

```cpp
FString GetId() const;   // IPersonBase::Execute_GetId(Obj)
```

The unique **`PersonId`** — the mocap system's per-person id. Stable for the life of the tracked person; the key used by [`GetPersonByPersonId`](/docs/sdk-api/unreal-api/classes/skeletonconsumer#getpersonbypersonid) and `PersonIdToCharacterBPMap`. See Id semantics above.

<Returns type="FString">the mocap `PersonId`</Returns>

</ApiBody>

### GetDeviceId

<ApiBody kind="method" tags="BlueprintCallable, BlueprintNativeEvent">

```cpp
FString GetDeviceId() const;   // IPersonBase::Execute_GetDeviceId(Obj)
```

The associated **device/headset id**. Distinct from `PersonId` — the device this person is wearing/using, when one is associated.

<Returns type="FString">the device/headset id, or empty if none is associated</Returns>

</ApiBody>

### GetCharacter

<ApiBody kind="method" tags="BlueprintCallable, BlueprintNativeEvent">

```cpp
UAR51Character* GetCharacter() const;   // IPersonBase::Execute_GetCharacter(Obj)
```

The mocap-driven [`UAR51Character`](/docs/sdk-api/unreal-api/classes/uar51character) component for this person — the usual hop to read joint state (head, wrists, hand joints). The consumer drives this component every frame; you read from it.

<Returns type="UAR51Character*" typeHref="/docs/sdk-api/unreal-api/classes/uar51character">the driven character component for this person</Returns>

<Example inferred>

```cpp
if (UObject* Obj = Person.GetObject())
{
    if (UAR51Character* Char = IPersonBase::Execute_GetCharacter(Obj))
    {
        const FVector L = Char->GetLeftWristPosition();    // UE cm
        const FVector R = Char->GetRightWristPosition();
    }
}
```

</Example>

</ApiBody>

### GetModel

<ApiBody kind="method" tags="BlueprintCallable, BlueprintNativeEvent">

```cpp
AActor* GetModel() const;   // IPersonBase::Execute_GetModel(Obj)
```

The spawned **actor** representing the person in the level (the [`AAR51CharacterActor`](/docs/sdk-api/unreal-api/classes/aar51characteractor) that hosts the character component). Use it for actor-level operations — attachment, visibility, world transform.

<Returns type="AActor*" typeHref="https://dev.epicgames.com/documentation/en-us/unreal-engine/API/Runtime/Engine/GameFramework/AActor">the spawned model actor for this person</Returns>

</ApiBody>

### GetLastUpdateTime

<ApiBody kind="method" tags="BlueprintCallable, BlueprintNativeEvent">

```cpp
float GetLastUpdateTime() const;   // IPersonBase::Execute_GetLastUpdateTime(Obj)
```

The timestamp (seconds) at which this person's skeleton was last updated. Pair with `GetTimeFromLastUpdate` to detect staleness.

<Returns type="float">seconds-stamp of the last update</Returns>

</ApiBody>

### GetTimeFromLastUpdate

<ApiBody kind="method" tags="BlueprintCallable, BlueprintNativeEvent">

```cpp
float GetTimeFromLastUpdate(float currentTime) const;   // IPersonBase::Execute_GetTimeFromLastUpdate(Obj, Now)
```

Elapsed time since the last update — effectively `currentTime - GetLastUpdateTime()`. Use it to gate logic on stale persons (e.g. mirror the consumer's `InactivePersonMaxSeconds` / `HidePersonMaxSeconds` thresholds).

<Params>
<Param name="currentTime" type="float">the current time, in seconds, on the same clock as `GetLastUpdateTime`</Param>
</Params>

<Returns type="float">elapsed seconds since this person was last updated</Returns>

</ApiBody>

### IsTracked

<ApiBody kind="method" tags="BlueprintCallable, BlueprintNativeEvent">

```cpp
bool IsTracked() const;   // IPersonBase::Execute_IsTracked(Obj)
```

Whether this person is **currently tracked**. A person can persist briefly while tracking is lost (until the consumer's removal thresholds elapse), so check this before trusting positional reads.

<Returns type="bool">`true` while the person is actively tracked</Returns>

<Example inferred>

```cpp
if (UObject* Obj = Person.GetObject(); Obj && IPersonBase::Execute_IsTracked(Obj))
{
    UE_LOG(LogTemp, Log, TEXT("Tracking %s"), *IPersonBase::Execute_GetId(Obj));
}
```

</Example>

</ApiBody>

## See also

- [`USkeletonConsumer`](/docs/sdk-api/unreal-api/classes/skeletonconsumer) — returns persons from `GetActivePerson` / `GetPersonByPersonId` / `GetPersonByEntityId` / `GetPersonById`
- [`UAR51Character`](/docs/sdk-api/unreal-api/classes/uar51character) — the driven character component returned by `GetCharacter`
- [`AAR51CharacterActor`](/docs/sdk-api/unreal-api/classes/aar51characteractor) — the spawned model actor returned by `GetModel`
- [Class index](/docs/sdk-api/unreal-api/classes) — all Unreal SDK types
