Skip to content

Physics

Read physics data, apply forces, and react to collisions - all configurable in the Inspector.

Jungle.Physics lets you work with Unity's physics engine without writing custom scripts. Apply forces and torques, set velocities, toggle kinematic mode, control colliders, navigate with NavMeshAgents, cast rays, and respond to collision and trigger events - all through composable commands you configure in the Inspector. For continuous behaviors like force pipelines or velocity decay, timed operations self-tick on FixedUpdate and handle timing automatically.

The package covers:

  • Value providers for Rigidbody, Collider, RaycastHit, gravity, and collision matrix data
  • Commands for composable physics, collider, NavMesh, physics settings, and raycast operations
  • Operations for both instant and timed physics behaviors (velocity decay, force pipelines)
  • Events that fire on collision and trigger callbacks
  • Raycasting utilities with caching and optional Jobs-based batching
  • Detection strategies for raycast and trigger-based object detection

Assembly dependencies: Jungle.Core, Jungle.Spatial, Jungle.Math, IProcess, Unity.Mathematics, Unity.Collections, Unity.Burst (optional, enables batched raycasting via JUNGLE_JOBS_ENABLED).


Value Providers

Value providers let you wire physics data - a Rigidbody reference, a raycast hit point, the global gravity vector - into any system that accepts a value source. Pick the provider you need from the Inspector dropdown; the consuming system never changes.

Technically, physics value providers follow the standard IValue<T> pattern. Use them with [SerializeReference] and [JungleClassSelection] to wire physics data into any system that accepts a value provider.

Rigidbody and Collider

Type Interface Description
SmartRigidbody ISmartComponent<Rigidbody> A Rigidbody field: direct reference, lookup, or resolved at runtime
SmartRigidbody2D ISmartComponent<Rigidbody2D> The 2D equivalent
SmartCollider ISmartComponent<Collider> A Collider field, same three modes
// Wire a Rigidbody into any system that needs one
[SerializeField]
private SmartRigidbody targetRigidbody;

// Read the Rigidbody
Rigidbody rb = targetRigidbody.Value;

See Smart Values for the Local / Dynamic / Copied-On-Init modes these fields share.

RaycastHit Data

Type Interface Description
CollisionHitValue ICollisionHitValue Stores a RaycastHit struct (point, normal, collider, etc.)
CollisionHitPositionValue IVector3Value Reads the hit position from an ICollisionHitValue
CollisionHitNormalValue IVector3Value Reads the hit normal from an ICollisionHitValue

These compose together: a RaycastHitCaptureCommand writes into a CollisionHitValue, and downstream systems read the position or normal through the derived values.

// Read hit position from a stored collision hit
[SerializeReference] [JungleClassSelection]
private IVector3Value hitPosition = new CollisionHitPositionValue();

Vector3 pos = hitPosition.Value();

Other Values

Type Interface Description
GravityValue IVector3Value Returns Physics.gravity - the global gravity vector
SmartNavMeshAgent ISmartComponent<NavMeshAgent> A NavMeshAgent field

Bounds-Driven Sizes

Several spatial value converters in jungle.spatial turn a Bounds into the size inputs physics queries expect. Combine with LocalGameObjectBounds and a Filtered Object source to drive shapes from the object being checked, not a hardcoded number.

Type Output Use For
BoundsSphereRadius IFloatValue Sphere overlap / sphere-cast radius.
BoundsExtents IVector3Value Box overlap half-extents (or full size). Per-axis multiplier.
BoundsHeight IFloatValue Single-axis size — capsule height, vertical-extent checks. Per-axis selection (X/Y/Z).

Filters

PhysicsOverlapFilter

A GameObjectFilter that probes for colliders around the filtered object's transform with a configurable shape (sphere / box / capsule). Use it as a detector predicate to express conditions like "only objects currently touching the floor" or "only objects clear of obstacles".

Field Description
shape Probe shape: Sphere, Box, or Capsule.
collisionMask (SmartLayerMask) Layers that count for the overlap.
triggerInteraction Whether triggers count, are ignored, or follow project default.
ignoreSelfColliders Skip colliders on the filtered object or its children.
rigidbodyRequirement Filter results by attached rigidbody: Any, AnyRigidbody, NonKinematicOnly, KinematicOnly.
hitFilters IGameObjectFilter list run on each touching collider's GameObject; it counts only when all pass. Empty counts every collider.
passOnOverlap true = filter passes when at least one collider overlaps. false = passes when clear.
sphereRadius (Sphere) SmartFloat. Drive from bounds via BoundsSphereRadius.
boxHalfExtents (Box) SmartVector3. Drive from bounds via BoundsExtents (HalfExtents mode).
capsuleRadius, capsuleHeight, capsuleAxis (Capsule) SmartFloat/SmartFloat/enum. Height is auto-clamped to ≥ 2 × radius.

Sized-by-bounds wiring. Inside the filter, the IGameObjectValue slot in LocalGameObjectBounds will offer Filtered Object in the picker (and only there — the picker hides it elsewhere). Wiring it makes the probe size scale automatically per filtered object:

PhysicsOverlapFilter
  └─ sphereRadius = SmartFloat (Dynamic)
       └─ Bounds Sphere Radius
            └─ Local GameObject Bounds
                 └─ gameObject = Filtered Object

The filter uses Physics.OverlapXxxNonAlloc with a fixed-size buffer (16) so it's allocation-free per call.


Commands

Commands are composable, one-shot operations. All physics commands follow the TargetedCommand<TTarget, TOperation> pattern: one target, multiple operations in a reorderable list. Operations run in parallel - instant ones complete immediately, timed ones self-tick. The command completes when all operations finish.

RigidBodyCommand

Extends TargetedCommand<Rigidbody, IPhysicsOperation>. Resolves a single Rigidbody and executes a list of IPhysicsOperation operations on it.

ProcessRigidbody Command
Target1Crate (Rigidbody)◎
Operations22+
Operation 1Set Kinematic
Operation 2Apply Force
Force080
Force ModeImpulse
Use Custom Position
Turn physics back on, then kick the crate upward: both operations start together.
  1. Target: the Rigidbody every operation acts on.
  2. Operations: one-line ones like Set Kinematic stay on a single row.
[SerializeReference]
[JungleList(typeof(IPhysicsOperation), Layout = JungleListLayout.Flat, EmptyLabel = "No operations", ElementLabel = "Operation")]
private List<IPhysicsOperation> operations = new();
// The Rigidbody target comes from the base command's SmartRigidbody field.

Built-in physics operations:

Operation Description
ApplyForce Applies a force vector with configurable ForceMode. Optionally applies at a custom world position for torque effects.
ApplyTorque Applies a torque vector with configurable ForceMode.
SetLinearVelocityAction Directly sets the rigidbody's linear velocity.
SetAngularVelocityAction Directly sets the rigidbody's angular velocity.
SetKinematic Sets kinematic, non-kinematic, or toggles.
SetGravity Enables, disables, or toggles useGravity.
SetLinearDamping Sets the rigidbody's linear damping (air resistance).
SetAngularDamping Sets the rigidbody's angular damping (rotational resistance).
SetConstraints Sets RigidbodyConstraints to freeze specific axes.
SetMass Sets the Rigidbody mass.
ForcePipelineOperation Reads a Vector3 target and applies it as a force each fixed tick. Optionally applies at a custom world position. Timed operation.
TorquePipelineOperation Reads a Vector3 target and applies it as torque each fixed tick. Timed operation.
QuaternionTorquePipelineOperation Converts a quaternion rotation target into proportional torque impulses with configurable strength and damping. Timed operation.
LinearVelocityPipeline Drives the rigidbody's linear velocity each fixed tick via a Vector3 target + modifier chain with a configurable completion check. Timed operation.
AngularVelocityPipeline Drives the rigidbody's angular velocity each fixed tick via a Vector3 target + modifier chain with a configurable completion check. Timed operation.
SetDetectCollisions Turns collision detection for the whole rigidbody on or off, covering every collider it owns. Turn it off while an object is carried so it cannot bump or push anything, and back on when it is released. While off, raycasts cannot see the object either.
SetExcludeLayers Chooses the layers the rigidbody passes through, covering every collider it owns. Raycasts still hit it, so an object parked in a slot with Everything excluded cannot bump anything yet stays hoverable and grabbable. Set it back to Nothing on release.

Example - launch an object upward and disable gravity:

var command = new RigidBodyCommand(
    new ApplyForce { force = Vector3.up * 10f, forceMode = ForceMode.Impulse },
    new SetGravity { mode = SetGravity.GravityMode.Disable }
);
command.Begin();

ColliderCommand

Extends TargetedCommand<Collider, IColliderOperation>. Resolves a single Collider and executes a list of IColliderOperation operations on it.

Built-in collider operations:

Operation Description
SetEnabled Enables, disables, or toggles the collider.
SetTrigger Controls the isTrigger flag.
SetPhysicsMaterial Assigns a PhysicsMaterial to the collider.
IgnoreCollisionWith Makes this collider and one other collider pass through each other, or collide again. Only that exact pair is affected -- no layer or collision matrix setup needed. Unity forgets the pairing whenever either collider is disabled.

Extends TargetedCommand<NavMeshAgent, INavMeshOperation>. Resolves a single NavMeshAgent and executes a list of INavMeshOperation operations on it.

Built-in NavMesh operations:

Operation Description
SetDestination Sets the agent's navigation target (transform or position).
SetNavMeshSpeed Changes agent speed.
SetNavMeshEnabled Enables or disables the agent.
StopNavMeshAgent Stops the agent.
ResumeNavMeshAgent Resumes the agent.
WarpNavMeshAgent Teleports the agent to a position.

PhysicsSettingsCommand

Executes a list of IPhysicsSettingsOperation operations on global physics settings. Unlike the targeted commands above, this one has no target component - it modifies Unity's global Physics settings directly.

Built-in physics settings operations:

Operation Description
SetGravityVector Sets the global gravity vector.
SetPhysicsIterations Configures solver iteration counts.

With Magpile installed, an Apply Collision Matrix operation joins this list. See State & Save.

RaycastHitCaptureCommand

Extends Command and executes a list of IRaycastOperation operations in parallel. Each operation performs a physics query (raycast, sphere cast, etc.) and stores results into value references for downstream systems to read.

// Configure in Inspector:
// - Each IRaycastOperation has its own ray origin, direction, and result storage
// - Operations run in parallel
// - Results are written into ICollisionHitValue / IColliderValue references
// On Execute(), the command runs all operations and writes results
// into the storage values for other systems to read.

Operations

Operations are the building blocks of physics commands. Each operation implements one of the operation interfaces and is either instant or timed.

Instant vs Timed Operations

Instant operations extend a convenience base class (e.g., InstantPhysicsOperation) and override a single Execute() method. They complete immediately when called.

Timed operations implement the operation interface directly (e.g., IPhysicsOperation) along with IFixedUpdatable to self-tick on FixedUpdate. They call onComplete when finished. Force pipelines and velocity decay are examples of timed operations.

Both types can be mixed freely in the same command's operation list - the command runs them in parallel and completes when all finish.

IPhysicsOperation

public interface IPhysicsOperation : IOperation
{
    void Begin(Rigidbody rb, Action onComplete);
}

Instant operations extend InstantPhysicsOperation and override Execute(Rigidbody rb). Timed operations implement IPhysicsOperation directly and call onComplete when their work is done.

Pipeline Operations

Pipeline operations are timed IPhysicsOperation implementations that run continuously on FixedUpdate. They combine a target value, modifiers, and an applier into a continuous physics-driven loop.

Operation Description
ForcePipelineOperation Reads a Vector3 target and applies it as a force to a Rigidbody each fixed tick. Optionally applies at a custom world position.
TorquePipelineOperation Reads a Vector3 target and applies it as torque to a Rigidbody each fixed tick.
QuaternionTorquePipelineOperation Converts a quaternion rotation target into proportional torque impulses with configurable strength and damping. Useful for physics-driven aiming or motorized joints.
LinearVelocityPipeline Drives a Rigidbody's linear velocity each fixed tick via a Vector3 target + modifier chain.
AngularVelocityPipeline Drives a Rigidbody's angular velocity each fixed tick via a Vector3 target + modifier chain.

Example - throwing an object with velocity decay:

Wire a velocity measurement into a LinearVelocityPipeline's target as the starting value and use a lerped target with a decay curve. The pipeline reads the current linear velocity each FixedUpdate, runs it through the modifier chain, and writes the result back to the rigidbody.

Operations1+
Operation 1Set Linear Velocity Over Time
Destination
Destination1(None)◎
Modifiers
Modifiers20+
None
Options
Set Linear Velocity Over Time inside a Rigidbody Command: it runs every physics step until it finishes.
  1. Destination: the velocity to drive toward, for example the measured throw velocity easing to zero.
  2. Modifiers: optional changes applied on the way, in order.

Events

Physics Event Relays

Family of MonoBehaviours that broadcast Unity's physics callbacks as C# events. Add the subclass that matches the callback family you need — each only registers its own Unity messages with the physics engine.

Component Listens for
Trigger3DRelay OnTriggerEnter / OnTriggerExit
Collision3DRelay OnCollisionEnter / OnCollisionExit
Trigger2DRelay OnTriggerEnter2D / OnTriggerExit2D
Collision2DRelay OnCollisionEnter2D / OnCollisionExit2D
Add Component > Jungle > Events > Trigger 3D Relay   (or Collision 3D Relay, etc.)

Need more than one family on the same GameObject? Add multiple relays — each only subscribes to its own Unity messages. All subclasses share PhysicsEventRelayBase and expose the same events; consumers (PhysicsEvent, PhysicsOverlapDetectionStrategy) only know about the base. Full reference: PhysicsEventRelay.

PhysicsEvent

A serializable IEvent implementation that monitors a physics relay. Configure the relay reference, event type, layer mask filter, and tag filter in the Inspector. Errors loudly at bind time if the chosen event type isn't emitted by the wired relay subclass.

// Use a PhysicsEvent to trigger any Jungle system on collision
[SerializeReference] [JungleClassSelection]
private IEvent onHit = new PhysicsEvent();

// In your setup code:
onHit.Register(() => Debug.Log("Something collided!"));

Supported event types (PhysicsEventType):

  • OnCollisionEnter, OnCollisionExit
  • OnTriggerEnter, OnTriggerExit
  • OnCollisionEnter2D, OnCollisionExit2D
  • OnTriggerEnter2D, OnTriggerExit2D

Filtering: Set the layerFilter mask and/or tagFilter list to restrict which colliding objects cause the event to fire.


Joints

JointBreakSignalSource

A MonoBehaviour that forwards Unity's OnJointBreak callback as a signal into a Reactor. Add it to the same GameObject that owns the joint.

Add Component > Jungle > Events > Joint Break Signal Source
Field Description
reactor Reactor that receives the signal. If empty, searched on this GameObject (and optionally parents/children).
searchParents Search parent hierarchy for a Reactor when none is assigned.
searchChildren Search child hierarchy for a Reactor when none is assigned.
signal Signal Key pushed into the Reactor when the joint breaks. Leave empty to skip the dispatch and only fire the local event.
onBroken UnityEvent\<float> invoked locally with the break force.

Wire a Signal Reaction on the target Reactor to run processes when the joint snaps. The onBroken event also fires with the break force value for local wiring.

Joint Measurement Command

Measures a joint for as long as it runs. Pick Joint Measurement Command as the process of a Process Component (or in a reaction's process), set its target to the joint, and add measurements. Each measurement writes into its own sink, for example a Float From Data Storage key, so a Reactor can watch thresholds on it. Measurements that need a specific joint type skip other joints.

Field Description
Target The joint to measure.
Measurements The joint measurements to run. Each writes into its own sink.
Inspector
Process Component? ⇅ ⋮
Process
Start & Stop
ProcessJoint Measurement Command
Target1Door (Hinge Joint)◎
Measurements1+
Measurement 1Hinge Angle
Scheduler2Execute Every Frame
Sink3Float From Data Storage
Modifiers0+
None
Reads the door's hinge angle every frame and stores it for reactions to use.
  1. Target: the joint to measure.
  2. Scheduler: how often it samples.
  3. Sink: where the angle is written.

Joint Measurements

Measurement Output Description
Hinge Angle float Current angle of a HingeJoint relative to its rest pose.
Hinge Angular Velocity float Angular velocity of a HingeJoint.
Joint Distance float World-space distance between the joint's anchor and its connected anchor. Detects stretch on spring or configurable joints.
Joint Force float Magnitude of the force the joint currently applies.
Joint Torque float Magnitude of the torque the joint currently applies.
Configurable Joint Twist float Twist angle of a ConfigurableJoint around its primary axis.
Configurable Joint Swing 1 float Swing angle of a ConfigurableJoint around its secondary axis.
Configurable Joint Swing 2 float Swing angle of a ConfigurableJoint around its tertiary axis.

Each measurement supports an optional modifier chain (clamping, remapping, curves; smoothing and filters come with Anteloope) and a configurable execution frequency. Pair with a Float Threshold or Float Range reaction on the same value to fire processes when values cross a boundary.


Raycasting

RaycastHitProvider

A serializable raycasting utility that encapsulates ray source, layer mask, max distance, trigger handling, caching, and optional batch processing.

Hit ProviderRaycast
Ray Value1Ray From Camera
Layer MaskDefault, Props
Max Distance100
Hit Triggers
Enable Caching2
Cache ModeTime
Cache Time Interval0.1
Use Batch Raycast3
A Raycast hit provider casting from the camera through the mouse, refreshed ten times a second.
  1. Ray Value: where the ray starts and points.
  2. Caching: cast less often; the interval field follows the mode.
  3. Batch: share the work across all raycasters when jobs are enabled.

Key features:

  • Ray source - configurable via IRayValue (defaults to camera ray from mouse position)
  • Caching - time-based or frame-based intervals to reduce raycast frequency
  • Batch raycasting - when JUNGLE_JOBS_ENABLED is defined, raycasts are submitted to the RaycastPerformanceManager for parallel execution via Unity Jobs; each result arrives one frame after its request
// Use a hit provider in your own systems
var raycaster = new RaycastHitProvider();
if (raycaster.TryGetHit(out RaycastHit hit))
{
    Debug.Log($"Hit {hit.collider.name} at {hit.point}");
}

Sharing raycasters: Put the configuration on a HitProviderAsset and drop a HitProviderFromAsset into any IHitProvider field, so several components cast the same way without each carrying its own copy.

SpreadNormalSampler

A static utility that averages surface normals from multiple rays spread in a cone pattern around a central ray. Useful for smoothing normals near surface edges.

Vector3 smoothedNormal = SpreadNormalSampler.Sample(
    mainNormal: hit.normal,
    mainRay: ray,
    sampleCount: 8,
    spreadAngleDeg: 5f,
    maxDistance: 100f,
    layerMask: ~0
);

RaycastPerformanceManager

A singleton that batches all raycast requests into a single RaycastCommand.ScheduleBatch call per frame using Unity Jobs. Only available when JUNGLE_JOBS_ENABLED is defined (requires the Burst package). Hit providers opt into this automatically via their useBatchRaycast toggle.


Detection Strategies

Detection strategies integrate with Jungle's detector system to report when objects enter or leave detection range.

Strategy Description
RaycastDetectionStrategy Periodically casts a ray and reports the hit GameObject. Only one object is detected at a time - when the ray hits a new object, the previous one is reported as lost.
PhysicsOverlapDetectionStrategy (shown as Trigger & Collision) Listens to a physics relay for enter/exit pairs. Pick the relay subclass to choose which Unity callbacks the engine actually fires (Trigger3DRelay, Collision3DRelay, or the 2D variants). Supports layer mask filtering.
// Configure a trigger-based detector in the Inspector
[SerializeReference] [JungleClassSelection]
private IDetectionStrategy detection = new PhysicsOverlapDetectionStrategy();

Utilities

RigidbodyExt

Extension methods on Rigidbody for common physics operations:

Method Description
Teleport(position, motionKept, jointAttached) Teleports a rigidbody (and optionally joint-attached bodies) while preserving or resetting velocity. Handles the kinematic toggle required for reliable position changes.
GetPushForceNeeded(target, ...) Calculates the force needed to push a rigidbody toward a target position, with configurable velocity and force clamping.
TargetPosition(target, ...) Applies the calculated push force directly.
TargetLookAt(lookDirection, normal, ...) Applies torque to rotate a rigidbody toward a look direction with angular velocity clamping.