PhysicsBodyComponent Class
Definition
Namespace: Brine2D.ECS.Components
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.
Inheritance System.Object → Component → 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](OnCollisionHit.md 'Brine2D\.ECS\.Components\.PhysicsBodyComponent\.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](PlatformNormalDirection.md 'Brine2D\.ECS\.Components\.PhysicsBodyComponent\.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](../SubShape/ShouldCollide.md 'Brine2D\.ECS\.Components\.SubShape\.ShouldCollide') delegate\) transitions between null and non-null. The system uses this to install or remove the Box2D custom filter callback. |