Nebula
Containers

PhysicsFrames

The physics frames this process holds, one per container with Container.OwnPhysicsFrame (docs/container-tree.md §3): scene lifetime and pooling, interior colliders, frame state, conversion between spaces, the crossing policy, and — on a ...

generated from the sources
public static class PhysicsFrames

The physics frames this process holds, one per container with Container.OwnPhysicsFrame (docs/container-tree.md §3): scene lifetime and pooling, interior colliders, frame state, conversion between spaces, the crossing policy, and — on a client — composing the frames into one rendered world.

Fields

PoolSize

public static int PoolSize = 8;

How many emptied frame scenes are kept for reuse, so a carrier spawning and despawning does not create and unload a scene each time (D13).

OriginShiftThreshold

public static float OriginShiftThreshold = 2048f;

How far, in metres, the entities a worker simulates in a frame may drift from the frame's origin before AutoShift moves the origin to them. Physics keeps millimetre precision well past this.

OriginShiftStep

public static float OriginShiftStep = 1024f;

The grid a moved origin snaps to, in metres, so two workers that shift for the same crowd agree.

RenderOriginThreshold

public static float RenderOriginThreshold = 256f;

How far (metres) the render anchor may be from a frame's own origin, and later from its render origin, before the frame is drawn about a render origin near the anchor (D25). Small, so that what the frame's turn multiplies stays a few hundred metres long: a float rotation turns 2 km with a few tenths of a millimetre of rounding. A ship's frame, with the anchor aboard, never needs one. float.PositiveInfinity turns render origins off.

RenderOriginStep

public static float RenderOriginStep = 128f;

The grid a render origin snaps to (metres), so it moves only as the anchor travels.

ShiftChildrenWhileDrawing

public static bool ShiftChildrenWhileDrawing = true;

While cameras draw, a frame drawn about a render origin has its -O moved from its root down to the root's direct children (D25): the root at zero under the pivot, each child at its own offset less O. Unity composes a pose from the leaf up, so with -O on the root, a body moving in a chunk 200 km out added its offset to the chunk's in float before -O was met, and rounded by a centimetre, differently every frame. With the children shifted, every sum stays a few hundred metres long. Everything is put back exactly when drawing ends, so no game code, and nothing Nebula reads (interpolation, prediction, the wire), sees the shifted poses. On by default; turn it off if your game draws outside Unity's camera callbacks.

HoldThroughFixedSteps

public static bool HoldThroughFixedSteps = true;

Client: whether a frame held at its simulation pose by a prediction step in FixedUpdate stays there through the rest of the frame's fixed steps, and goes back to its render pose once, as the frame's PreUpdate starts (NEB-445). A client whose frame rate is below its tick rate runs several fixed steps a frame, and each moved the frame twice. While held, scripts' FixedUpdate and the physics step see the predicting frame at its simulation pose (InSimulationPose is true for it): what they read and cast in the frame through its own objects agrees, but a ray from the camera does not meet the frame where it is drawn. Turn this off if your game casts into a frame in render coordinates during FixedUpdate; the frame then goes back after each NebulaClient.FixedUpdate. Update, LateUpdate and drawing see every frame at its render pose either way. While it is on, NebulaClient also replays a correction of its pawn in a frame in the next fixed step's hold instead of in Update, so a frame moves at most once into its simulation pose and once back each rendered frame, whatever the correction rate.

Properties

All

public static IReadOnlyList<PhysicsFrame> All { get; }

Every frame this process holds.

CrossingPolicy

public static IFrameCrossingPolicy CrossingPolicy { get; set; }

The game's say over crossings (D16). Null allows every crossing.

RendersFrames

public static bool RendersFrames { get; }

This process renders frames: a client, whose frame roots are posed at each frame's world pose outside its prediction step (D11). A worker never does, and converts poses itself when an entity changes space.

RenderAnchor

public static Transform RenderAnchor { get; set; }

What frames are drawn about on a client (D25): a frame whose content is drawn far from its own origin is posed about a point near this transform, so what is near it is composed without rounding through the frame's turn times a far offset. Set it to the camera when the camera can be far from the content anchor; null (the default) uses the client's content anchor (NebulaClient.ActiveContentAnchor: the local pawn, or whatever NebulaClient.SetContentAnchor was given).

Events

Created

public static event Action<PhysicsFrame> Created;

A frame was created (its container registered here). The game may add content to PhysicsFrame.Root.

Releasing

public static event Action<PhysicsFrame> Releasing;

A frame is about to be released (its container is leaving this process).

Methods

DrainPool

public static void DrainPool();

Unload every pooled scene (a world unloaded, a test tearing down).

Convert

public static Vector3 Convert(Vector3 point, Container from, Container to);
public static Quaternion Convert(Quaternion rotation, Container from, Container to);

A point in space from expressed in space to. A space is a framed container (its frame's local coordinates) or null (the scope's own space). Walks up from from to the space both share and down into to through each frame owner's transform, so it is exact at this instant in simulation space — which is where a worker is, always.

ConvertVelocity

public static Vector3 ConvertVelocity(Vector3 velocity, Vector3 point, Container from, Container to);

A velocity of a body at point (in space from) expressed in space to: rotated, plus the motion of every frame left (its velocity and ω × r), minus the motion of every frame entered, from each frame's PhysicsFrame.State.

ShiftOrigin

public static void ShiftOrigin(PhysicsFrame frame, Vector3 origin);

Move frame's floating origin to the frame-local point origin (D19): its root, and with it everything in the frame, moves in simulation space so that point sits at Unity's origin. Frame-local coordinates do not change, so nothing on the wire does. The pose history and interpolation buffers of the entities in the frame are moved with it, and PhysicsFrame.Shifted reports the delta for anything else. Worker only: a client renders every frame at its world pose.

CommonSpace

public static Container CommonSpace(Container a, Container b);

The innermost space both lie in (null: the scope's own space).

ToScope

public static Vector3 ToScope(Vector3 position, Container space);

A position given in space space as a position in the scope's own space: what a game uses to relate something inside a frame to something outside it (a shot fired out through a window, a distance for a sound). Simulation space; on a client in render space every position is already a scope position.

FromScope

public static Vector3 FromScope(Vector3 position, Container space);

The inverse of ToScope.

DirectionToScope

public static Vector3 DirectionToScope(Vector3 direction, Container space);

ToScope for a direction (rotated only).

DirectionFromScope

public static Vector3 DirectionFromScope(Vector3 direction, Container space);

FromScope for a direction (rotated only).

ConvertLocal

public static Double3 ConvertLocal(Double3 point, Container from, Container to);
public static Quaternion ConvertLocal(Quaternion rotation, Container from, Container to);

A point in from's frame-local coordinates expressed in to's, composed in double. Frame-local coordinates are a frame's own (PhysicsFrame.SimulationToLocal): what an entity standing directly in the frame sends on the wire, the same on every process whatever the frame's floating origin. Null is the scope's own space. Unlike Convert, the point never passes through a float in the scope's space on the way, so a frame whose carrier stands hundreds of thousands of kilometers from the scope's origin (a planet in its star system) converts to the millimeter. Each frame's pose is its carrier's transform as this process has it: on a worker, the simulated pose.

SourceOf

public static Collider SourceOf(Collider hit);

The collider a frame's interior copy was made from (D12): a raycast inside a frame hits the copies, and game code that looks for components on what it hit (a seat, a door button) wants the original on the carrier. Returns hit itself when it is not a copy.

InSimulationPose

public static bool InSimulationPose(Container space);

Whether space's frame root is at its simulation pose right now (the identity less the frame's floating origin, PhysicsFrame.LocalToSimulation): always on a worker, and on a client during a prediction step (BeginSimulation) and while the frame is held at that pose between steps (EndSimulation). False for the scope's own space.

PoseForRender

public static void PoseForRender();

Client: put every frame root at its frame's world pose, outermost frames first, so the camera sees one world. Called by NebulaClient every rendered frame after remote entities were interpolated, and after every origin shift of the scope (RuntimeGrid.ShiftOrigin, RuntimeGrid.ShiftOriginTo), so what stands in a frame moves with the origin at once. A frame that is simulating (a prediction step) is left at its simulation pose. A frame drawn far from its own origin is posed about a render origin (D25).

BeginSimulation

public static void BeginSimulation(Container space);
public static void BeginSimulation(Container space, Transform predicted);

Client: put space's frame root at its simulation pose for a prediction step, so the predicted pawn simulates exactly as its worker does (D11): the identity less the frame's floating origin. Pair with EndSimulation. BeginSimulation first moves that origin near what is predicted.

EndSimulation

public static void EndSimulation();
public static void EndSimulation(bool hold);

Client: the prediction step is over; the frame goes back to its render pose.

ReleaseSimulationPose

public static void ReleaseSimulationPose();

Client: put a frame held at its simulation pose (EndSimulation) back at its render pose. Does nothing when no frame is held.

On this page