PhysicsBodyComponent Class

Component that defines a physics body and collision shape for an entity. Set Shape to any ShapeDefinition subtype to configure the primary shape. Additional shapes can be attached via AddSubShape(ShapeDefinition, bool, Nullable<float>, Nullable<float>). Pure data — logic handled by the physics system.

public class PhysicsBodyComponent : Brine2D.ECS.Component

Inheritance System.ObjectComponent → PhysicsBodyComponent

Properties
ActiveContactSubShapes Sub-shape pairs for active contact pairs, keyed by other body's index1.
ActiveSensorSubShapes Sub-shape pairs for active sensor overlaps, keyed by other body's index1.
BodyType How this body participates in physics simulation. Changes to a live body use a lightweight B2.BodySetType call — no full rebuild. Note that switching to Dynamic re-applies mass from shapes.
CategoryBits Raw category bitmask for this body's shapes. When non-zero, overrides the single-bit mask derived from Brine2D.ECS.Components.PhysicsBodyComponent.Layer (i.e. 1UL << Layer), allowing a body to belong to multiple collision categories simultaneously. Example: CategoryBits = (1UL << 0) | (1UL << 3) makes this body a member of both layer 0 and layer 3 for the purpose of collision filtering. Set to 0 (default) to use the single-layer behaviour driven by Brine2D.ECS.Components.PhysicsBodyComponent.Layer.
CenterOfMassOverride Overrides the body-local center of mass offset in pixels. When set, the physics system applies this after computing mass from shapes. Set to null to use the geometry-derived center. Changes on a live body apply immediately.
CollidingBodies Returns all bodies currently in active contact or sensor overlap with this body. This is the union of Brine2D.ECS.Components.PhysicsBodyComponent.ActiveContactPairs and Brine2D.ECS.Components.PhysicsBodyComponent.ActiveSensorPairs.
EnableHitEvents Whether hit events (OnCollisionHit) are enabled for this body's primary shape. Defaults to true. Changes on a live body apply immediately without a full rebuild.
FreezePositionX When true, the physics system zeroes the X component of this body's linear velocity every fixed-update step. Only affects Dynamic bodies.
FreezePositionY When true, the physics system zeroes the Y component of this body's linear velocity every fixed-update step. Only affects Dynamic bodies.
GravityOverride Overrides the world gravity direction and magnitude for this body in pixels per second squared. When set, world gravity and GravityScale are both ignored for this body; the physics system applies the override as a manual force each fixed-update frame. Set to null to restore normal gravity.
GravityScale Scales the world gravity applied to this body. Default is 1. Set to 0 to disable gravity on this body without changing the world gravity or providing a direction. Ignored when GravityOverride is set.
GroupIndex Box2D collision group index. Positive values cause members of the same group to \<em>always\</em> collide with each other regardless of category/mask bits. Negative values cause members of the same group to \<em>never\</em> collide with each other. Zero (default) disables group-index logic and falls back to category/mask filtering.
InitialAngularVelocity Angular velocity (radians/s) applied to the body when it is first created. Has no effect once the body is live — use Brine2D.ECS.Components.PhysicsBodyComponent.AngularVelocity instead. Has no meaningful effect on Kinematic bodies because the physics system derives angular velocity from rotation delta on every fixed-update frame.
InitialLinearVelocity Linear velocity applied to the body when it is first created by the physics system. Has no effect once the body is live — use LinearVelocity instead. Has no meaningful effect on Kinematic bodies because the physics system derives velocity from position delta on every fixed-update frame.
IsBodyTypeDirty Set by the physics system when only BodyType has changed on a live body. The system calls B2.BodySetType instead of a full rebuild, preserving position, velocity, and all attached shapes.
IsBullet
IsBulletDirty Set when IsBullet changes on a live body. The physics system performs a full body rebuild (bullet mode cannot be changed without recreating the body in Box2D), preserving the current velocity.
IsFilterDirty Set by the physics system when only the collision filter (layer/mask) has changed on a live body. The system applies a lightweight B2.ShapeSetFilter call instead of a full body rebuild, preserving velocity and sleeping state.
IsMassDirty Set by the Mass setter when the body is already live. The system calls B2.BodyApplyMassFromShapes instead of a full rebuild, preserving position, velocity, contacts, and sleeping state.
IsMaterialDirty Set when SurfaceFriction, Restitution, or EnableHitEvents changes on a live body. The system calls B2.ShapeSetFriction, B2.ShapeSetRestitution, and B2.ShapeEnableHitEvents instead of a full rebuild.
IsOneWayPlatform When true, this body acts as a one-way platform: bodies approaching from the non-solid side (opposite to PlatformNormalDirection) pass through, while bodies approaching from the solid side collide normally.
IsSimulationEnabled When false, the Box2D body is removed from the broad-phase: it stops moving, stops colliding, and does not appear in queries. All shapes, joints, and body data are preserved so simulation resumes correctly when set back to true. Defaults to true.
IsSimulationEnabledDirty Set when IsSimulationEnabled changes on a live body so the physics system can flush contact/sensor pair state and fire exit events on the next tick.
IsSubShapeGeometryDirty Set when UpdateDefinition(ShapeDefinition) is called with a same-type shape on a live body. The system calls B2.ShapeSet* instead of a full rebuild, preserving contacts, velocity, and sleeping state. A type-changing update marks Brine2D.ECS.Components.PhysicsBodyComponent.IsDirty instead.
IsSubShapeTriggerDirty Set when IsTrigger changes on a live body sub-shape. The system calls B2.ShapeEnableSensorEvents and B2.ShapeEnableContactEvents on the affected sub-shape, updates density, and flushes stale contact/sensor pairs — no full rebuild is required.
IsTeleporting Set by Teleport(Vector2, Nullable<float>) to tell the physics system to reset the kinematic previous-position and previous-rotation records, suppressing the phantom velocity that would otherwise be derived from the discontinuous displacement.
IsTrigger When true, this body acts as a sensor: it reports overlaps via OnTriggerEnter / OnTriggerStay / OnTriggerExit but generates no collision response forces.
LinearVelocity Gets or sets the linear velocity of this body in pixels per second.
Mass Mass of the body in simulation units. Must be greater than zero. Default is 1.
Material Applies a PhysicsMaterial preset, setting SurfaceFriction and Restitution in one assignment.
Offset Translates the physics body's origin relative to the entity's Position in pixels.
PlatformNormalDirection The outward normal of the solid surface in world space (does not need to be normalized). Default is (0, -1) — solid from above in Y-down screen space. Only used when IsOneWayPlatform is true.
Restitution Bounciness of this body's primary shape (0–1). Changes on a live body apply immediately without a full rebuild.
RotationalInertiaOverride Overrides the rotational inertia of the body in simulation units. Must be greater than zero when set. Set to null to use the geometry-derived value. Changes on a live body apply immediately. Has no effect on Static or Kinematic bodies.
Shape The primary collision shape for this body. Assign any ShapeDefinition subtype: CircleShape, BoxShape, CapsuleShape, PolygonShape, or ChainShape. Setting this marks the body dirty and triggers a rebuild on the next physics step.
ShouldCollide Per-body collision filter. When set, called for every candidate contact pair involving this body — return false to prevent the pair from colliding or triggering. Both bodies in the pair are checked; either can veto the contact. The callback is invoked from the Box2D broad-phase on the simulation thread — keep it allocation-free.
SleepThreshold The sleep speed threshold for this body in simulation units per second. When the body's linear and angular speed drops below this value it becomes eligible for sleeping. Set to 0 to use the Box2D world default. Changes on a live body apply immediately.
SurfaceFriction Surface friction of this body's primary shape (0–1). Changes on a live body apply immediately without a full rebuild.
Methods
AddSubShape(ShapeDefinition, bool, Nullable<float>, Nullable<float>) Adds an additional collision shape to this body. Chain shapes are not supported as sub-shapes.
ApplyForceAtLocalPoint(Vector2, Vector2) Applies a force at a local-space point, generating both linear and angular acceleration. localPoint is in the body's local coordinate frame.
ApplyLinearImpulseAtLocalPoint(Vector2, Vector2) Applies a linear impulse at a local-space point, generating both linear and angular velocity changes. localPoint is in the body's local coordinate frame.
GetContacts(Span<ContactPair>) Reads the live contact manifolds for this body directly from Box2D, written into results. Returns the number of contacts written. Returns 0 if the body is not live, has no active contacts, or the component has not been registered with a PhysicsWorld.
GetContacts(Span<ContactPair>, bool) Reads the live contact manifolds for this body directly from Box2D, written into results. Returns the number of contacts written. Returns 0 if the body is not live, has no active contacts, or the component has not been registered with a PhysicsWorld.
GetContactsAll(List<ContactPair>) Reads all live contact manifolds for this body into results, retrying internally with a larger buffer until every contact is captured. Clears results before writing. Delegates to GetContactsAll(PhysicsBodyComponent, List<ContactPair>).
GetVelocityAtPoint(Vector2) Returns the velocity of this body at a given world-space point, accounting for both linear and angular velocity. Useful for computing impact speed at a contact point. Returns System.Numerics.Vector2.Zero if the body is not live.
GetWorldPosition() Returns the physics-side world-space position of this body (body pivot, not entity origin). Includes the Offset — equivalent to transform.Position + Offset when the body is live. Returns System.Numerics.Vector2.Zero if the body has not yet been created.
GetWorldRotation() Returns the physics-side world-space rotation of this body in radians. Returns 0 if the body has not yet been created.
InverseTransformDirection(Vector2) Converts a direction vector from world space to local body space (rotation only, no translation). Returns the vector unchanged if the body has not yet been created.
InverseTransformPoint(Vector2) Converts a point from world space to local body space using the body's current live transform. Returns the point unchanged if the body has not yet been created.
Teleport(Vector2, Nullable<float>) Instantly moves this body to position (and optionally sets its rotation) without triggering a full body rebuild. Linear and angular velocity are preserved. For kinematic bodies the previous-position and previous-rotation records are also reset, preventing a phantom velocity spike on the next fixed update.
TransformDirection(Vector2) Converts a direction vector from local body space to world space (rotation only, no translation). Returns the vector unchanged if the body has not yet been created.
TransformPoint(Vector2) Converts a point from local body space to world space using the body's current live transform. Returns the point unchanged if the body has not yet been created.
TryGetAABB(Vector2, Vector2) Computes the world-space axis-aligned bounding box that encloses all shapes on this body. Returns false if the body has not yet been created by the physics system.
Events
OnBodySleep Fired once when this body falls asleep.
OnBodyWake Fired once when this body wakes from sleep.
OnCollisionEnter Fired once when another body begins touching this body.
OnCollisionEnterWithShape Fired once when another body begins touching this body, with sub-shape detail. The first SubShape is the sub-shape on \<em>this\</em> body that was hit (null when the primary shape was hit). The second is the sub-shape on the \<em>other\</em> body (null when its primary shape was hit).
OnCollisionExit Fired once when another body stops touching this body.
OnCollisionExitWithShape Fired once when another body stops touching this body, with sub-shape detail. Arguments mirror OnCollisionEnterWithShape.
OnCollisionHit Fired once when a high-speed contact impact is detected. ImpactSpeed contains the closing speed.
OnCollisionStayWithShape Fired every fixed-update tick while this body remains in contact with another body, with sub-shape detail.
OnTriggerEnter Fired once when another body begins overlapping this trigger.
OnTriggerEnterWithShape Fired once when another body begins overlapping this trigger, with sub-shape detail. The first SubShape is the sub-shape on \<em>this\</em> body that acted as the sensor (null when the primary shape was the sensor). The second is the sub-shape on the \<em>visitor\</em> body (null when its primary shape overlapped).
OnTriggerExit Fired once when another body stops overlapping this trigger.
OnTriggerExitWithShape Fired once when another body stops overlapping this trigger, with sub-shape detail. Arguments mirror OnTriggerEnterWithShape: the first sub-shape is on \<em>this\</em> body, the second is on the \<em>visitor\</em> body.
OnTriggerStay Fired each fixed-update frame while a trigger overlap persists.
OnTriggerStayWithShape Fired each fixed-update frame while a trigger overlap persists, with sub-shape detail. Arguments mirror OnTriggerEnterWithShape.
ShouldCollideChanged Raised by the physics system when the ShouldCollide delegate (or any sub-shape ShouldCollide delegate) transitions between null and non-null. The system uses this to install or remove the Box2D custom filter callback.