Nebula
Core

RemoteInterpolator

Tick-indexed pose buffer for copies of an entity this process does not simulate: ghosts on a worker and remote entities on a client.

generated from the sources
public sealed class RemoteInterpolator : MonoBehaviour

Tick-indexed pose buffer for copies of an entity this process does not simulate: ghosts on a worker and remote entities on a client. The consumer decides at which (fractional) tick to sample.

Samples are kept in the space they arrived in: container-local, tagged with the container. A pose inside a moving container (a passenger on a ship) is therefore interpolated relative to the ship, and the sampled local pose is applied under the ship's transform wherever the ship is now, so passengers never lag a frame behind the hull. A sample with no container is a world pose (an entity outside every container).

Fields

Samples, Starved

public static long Samples, Starved;

Process-wide sample statistics, reset by whoever reports them (NebulaClient's telemetry line).

DepthSum, MaxOvershoot

public static double DepthSum, MaxOvershoot;

Properties

LatestTick

public uint LatestTick { get; }

HasSamples

public bool HasSamples { get; }

LatestScale

public Vector3 LatestScale { get; } = Vector3.one;

LatestAngularVelocity

public Vector3 LatestAngularVelocity { get; }

Angular velocity of the newest sample, in its container's local space, radians per second (zero when the stream does not carry one).

LatestHasAngularVelocity

public bool LatestHasAngularVelocity { get; }

Whether the newest sample carried an angular velocity (protocol 30, NetworkTransform.SyncAngularVelocity).

LatestVelocity

public Vector3 LatestVelocity { get; }

World-space velocity of the newest sample (what the authority reported).

LatestContainer

public Container LatestContainer { get; }

Container of the newest sample (null: world space).

LatestLocalPosition

public Vector3 LatestLocalPosition { get; }

Position of the newest sample, in LatestContainer's space.

LatestLocalRotation

public Quaternion LatestLocalRotation { get; } = Quaternion.identity;

LatestPosition

public Vector3 LatestPosition { get; }

World position of the newest sample, through its container's current frame.

LatestRotation

public Quaternion LatestRotation { get; }

Methods

ResetStats

public static void ResetStats();

Push

public void Push(uint tick, Container container, Vector3 localPosition, Quaternion localRotation, Vector3 velocity, Vector3? scale = null);
public void Push(uint tick, Container container, Vector3 localPosition, Quaternion localRotation, Vector3 velocity, Vector3 angularVelocity, bool hasAngularVelocity, bool hasVelocity, Vector3? scale = null);
public void Push(uint tick, Vector3 position, Quaternion rotation, Vector3 velocity);

Record a pose expressed in container's local space (world space when null). velocity is world-space.

Shift

public void Shift(Vector3 delta);

The floating origin moved: buffered world poses follow. Container-local poses need nothing (their containers moved).

Clear

public void Clear();

Sample

public bool Sample(double renderTick, out Container container, out Vector3 localPosition, out Quaternion localRotation);
public bool Sample(double renderTick, out Vector3 position, out Quaternion rotation);

Interpolated pose at renderTick, in the space of container (the newer sample's container; null means world). Falls back to extrapolating from the newest sample by its velocity (capped) when asked for a time we have not received yet. Apply it with NetworkIdentity.SetLocalPose so an entity under a moving container lands where the container is this frame.

On this page