FrameAttachment
Fixes an entity to a container at a pose in the container's space: a crate strapped to a cargo grid in a ship's hold, a turret bolted to a deck, a crate set on a shelf in a building.
Nebula · Packages/com.1by3.nebula/Runtime/Core/FrameAttachment.cs[DisallowMultipleComponent]
public sealed class FrameAttachment : NetworkBehaviourFixes an entity to a container at a pose in the container's space: a crate strapped to a cargo grid in a ship's hold, a turret bolted to a deck, a crate set on a shelf in a building. An attached entity does not slide, is not moved into a neighboring container, keeps its attachment through a handover, a restore from the store and a late joiner's spawn, and is let go gently. Add it to any entity, with or without a NetworkRigidbody.
The authority calls Attach, at a pose or, with no arguments, where the entity is now, and Detach; any worker holding a copy can ask with RequestAttach and RequestDetach. It works in a ship's physics frame, in a fixed container (a building, a chunk) and in a carrier without a frame. While attached:
- the entity sits in the container it is attached to, and the worker's tick does not re-resolve its container from its position. It is still handed to the worker that owns the container, so an entity attached to a container another worker owns moves there on the next tick, and a re-deal of the container takes it along;
- its body, if it has one, is kinematic on the authority, and its pose is put back at the attached pose every tick, so other bodies can rest on it;
- when its container changes for any other reason (its carrier despawned and set it down, it was placed somewhere else), it detaches.
A detach keeps the entity in its container, where it is. Its body turns dynamic with the velocity the attached pose had over the last tick (zero in a physics frame or a fixed container, the carrier's velocity in a carrier without a frame), and for DetachSettleTicks the body's depenetration speed is capped at DetachDepenetrationVelocity, so a crate attached slightly inside another is eased apart. The attachment is saved with a PersistentEntity and comes back attached, including as cargo stowed with CargoPolicy.Stow. See docs/frame-bodies.md §2.
Fields
DetachSettleTicks
public int DetachSettleTicks = 10;For this many ticks after a detach the body's depenetration speed is capped at DetachDepenetrationVelocity, so an overlap is eased apart instead of launching the body.
DetachDepenetrationVelocity
public float DetachDepenetrationVelocity = 1f;The body's depenetration speed, in m/s, for DetachSettleTicks ticks after a detach.
Properties
Attached
public bool Attached { get; }The entity is attached to its container. The same on every process that holds it.
AttachedTo
public Container AttachedTo { get; }The container the entity is attached to (always the container it is in), or null when it is not attached.
AttachedLocalPosition
public Vector3 AttachedLocalPosition { get; }The attached pose's position in the container's space. Known on the authority; meaningless when not attached.
AttachedLocalRotation
public Quaternion AttachedLocalRotation { get; } = Quaternion.identity;The attached pose's rotation in the container's space. Known on the authority; meaningless when not attached.
Events
AttachedChanged
public event Action<bool> AttachedChanged;The entity was attached (true) or detached (false). Raised on every process that holds the entity: on the authority when it happens, on ghosts and clients when they hear of it, and when an attached entity spawns on a process, a late joiner included.
Methods
Attach
public bool Attach(Container container, Vector3 localPosition, Quaternion localRotation, bool teleport = false);
public bool Attach();Authority: attach the entity to container at a pose in the container's space, moving it into the container first. Pass teleport to make remote copies snap to the pose instead of interpolating there. Attaching an attached entity moves the attachment. Returns false, with a warning, when this process is not the entity's authority or the container cannot hold the entity (one it carries itself).
Detach
public bool Detach();Authority: let the entity go, where it is, in the container it is in. Returns false when it was not attached or this process is not its authority.
RequestAttach
public void RequestAttach(Container container, Vector3 localPosition, Quaternion localRotation, bool teleport = false);
public void RequestAttach();From any worker that simulates or ghosts the entity: ask its authority to Attach. The container is named by its id, so it must be known on the authority's worker too.
RequestDetach
public void RequestDetach();From any worker that simulates or ghosts the entity: ask its authority to Detach it.
NetworkTick
public override void NetworkTick(uint tick, float deltaTime);OnNetworkSpawn
public override void OnNetworkSpawn();OnNetworkDespawn
public override void OnNetworkDespawn();OnGainedAuthority
public override void OnGainedAuthority();OnLostAuthority
public override void OnLostAuthority();OnContainerChanged
public override void OnContainerChanged(Container previous, Container current);OnOriginShifted
public override void OnOriginShifted(Vector3 delta);WriteHandoverState
public override void WriteHandoverState(NetworkWriter writer);ReadHandoverState
public override void ReadHandoverState(NetworkReader reader);WritePersistentState
public override void WritePersistentState(NetworkWriter writer);Always saved, attached or not, so the record is the one source of truth: a version byte, the flag, and the attached pose when attached (docs/frame-bodies.md D14).
ReadPersistentState
public override void ReadPersistentState(NetworkReader reader);DotEnv
Reads and writes dotenv files (.env.nebula, the file NEBULA_ENV_FILE names, nebula env pull output), and holds the rules for the names of the environment variables a game gives its workers.
FrameInertia
Lets a physics prop inside a moving physics frame feel the frame's motion: crates slide aft when the ship accelerates, outwards when it turns.