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 and processes you configure in the Inspector. For continuous behaviors like force pipelines or velocity decay, dedicated processes run 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, and NavMesh operations
  • Processes for time-based 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, 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
RigidbodyValue IRigidbodyValue / ISettableRigidbodyValue Direct reference to a Rigidbody component
ColliderValue IColliderValue / ISettableColliderValue Direct reference to a Collider component
// Wire a Rigidbody into any system that needs one
[SerializeReference] [JungleClassSelection]
private IRigidbodyValue targetRigidbody = new RigidbodyValue();

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

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
CollisionMatrixValue ICollisionMatrixValue Stores a CollisionLayerMatrix snapshot
NavMeshAgentValue INavMeshAgentValue Direct reference to a NavMeshAgent component
PhysicsEventRelayValue IPhysicsEventRelayValue Direct reference to a PhysicsEventRelay component

Commands

Commands are instant, one-shot operations. All physics commands follow Jungle's composable action-list pattern: one target, multiple toggleable operations in a reorderable list.

PhysicsCommand

Executes a list of IPhysicsAction operations on a single Rigidbody.

[SerializeReference] [JungleClassSelection]
private IRigidbodyValue targetRigidbody = new RigidbodyValue();

[SerializeReference]
[JungleClassSelection(typeof(IPhysicsAction), ToggleSet = true)]
private List<IPhysicsAction> actions = new();

Built-in physics actions:

Action 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.
SetVelocity Directly sets linear velocity, angular velocity, or both.
SetKinematic Sets kinematic, non-kinematic, or toggles.
SetGravity Enables, disables, or toggles useGravity.
SetDrag Sets linear and/or angular damping.
SetConstraints Sets RigidbodyConstraints to freeze specific axes.

Example - launch an object upward and disable gravity:

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

ColliderCommand

Executes a list of IColliderAction operations on a single Collider.

Built-in collider actions:

Action Description
SetEnabled Enables, disables, or toggles the collider.
SetTrigger Controls the isTrigger flag.
SetPhysicsMaterial Assigns a PhysicsMaterial to the collider.

ColliderStateCommand

A simpler alternative that enables, disables, or toggles colliders directly. Supports multi-value providers (operating on multiple colliders at once).

Executes a list of INavMeshAction operations on a single NavMeshAgent.

Built-in NavMesh actions:

Action 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.

Collision Matrix Commands

Three commands work together for save/restore collision matrix workflows:

Command Description
CollisionMatrixStoreCommand Snapshots the current global collision matrix.
CollisionMatrixOverrideCommand Applies a custom CollisionLayerMatrix to the global physics settings.
CollisionMatrixRestoreCommand Reverts to the previously stored matrix snapshot.

RaycastHitCaptureCommand

Casts a ray from an origin along a direction and stores the result into ICollisionHitValue and IColliderValue references. Supports batch raycasting when JUNGLE_JOBS_ENABLED is defined.

// Configure in Inspector:
// - rayOrigin: IVector3Value (e.g., transform position)
// - rayDirection: IVector3Value (e.g., transform forward)
// - hitStorage: ICollisionHitValue (writable)
// - colliderStorage: IColliderValue (writable)
// On Execute(), the command casts the ray and writes results
// into the storage values for other systems to read.

Processes

Processes are time-based operations that run across multiple frames, ticking on FixedUpdate for physics correctness.

PhysicsProcess

The process counterpart to PhysicsCommand. Runs a sequential list of IPhysicsProcessAction items on a single Rigidbody. Each action runs to completion before the next begins.

public interface IPhysicsProcessAction
{
    void Begin(Rigidbody rb, Action onComplete);
    void Complete();
    void FixedTick(Rigidbody rb, float fixedDeltaTime);
    bool IsRunning { get; }
    bool IsComplete { get; }
}

Built-in process action:

Action Description
ApplyVelocityOverTimeAction Applies a velocity that decays over a duration using an AnimationCurve. Reads the initial velocity from an IVector3Value. Supports force-based or direct velocity override modes.

Example - throwing an object with velocity decay:

Wire a velocity measurement into the velocitySource field, set a duration (e.g., 0.5s), and configure the fade curve. When the process begins, it captures the current velocity and applies it with decreasing strength each FixedUpdate.

Physics Pipelines

Pipelines combine a target value, modifiers, and an applier into a continuous physics-driven loop. They extend Vector3PhysicsPipelineProcess and run on FixedUpdate.

Pipeline Description
ForcePipeline Reads a Vector3 target and applies it as a force to a Rigidbody each fixed tick. Optionally applies at a custom world position.
TorquePipeline Reads a Vector3 target and applies it as torque to a Rigidbody each fixed tick.
QuaternionTorquePipeline Converts a quaternion rotation target into proportional torque impulses with configurable strength and damping. Useful for physics-driven aiming or motorized joints.

Events

PhysicsEventRelay

A MonoBehaviour that broadcasts Unity's physics callbacks as C# events. Add it to any GameObject that needs to be monitored.

Add Component > Jungle > Events > Physics Event Relay

The relay exposes 3D and 2D events:

Event Callback
CollisionEntered / CollisionExited OnCollisionEnter / OnCollisionExit
TriggerEntered / TriggerExited OnTriggerEnter / OnTriggerExit
CollisionEntered2D / CollisionExited2D OnCollisionEnter2D / OnCollisionExit2D
TriggerEntered2D / TriggerExited2D OnTriggerEnter2D / OnTriggerExit2D

PhysicsEvent

A serializable IEvent implementation that monitors a PhysicsEventRelay. Configure the event type, layer mask filter, and tag filter in the Inspector.

// 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.


Raycasting

Raycaster

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

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
// Use a Raycaster in your own systems
var raycaster = new Raycaster();
if (raycaster.Cast(out RaycastHit hit))
{
    Debug.Log($"Hit {hit.collider.name} at {hit.point}");
}

Sharing raycasters: Use RaycasterValue for inline references or RaycasterValueAsset (ScriptableObject) to share a single raycaster configuration across multiple components.

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). Raycasters 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.
TriggerDetectionStrategy Listens to a PhysicsEventRelay for trigger enter/exit callbacks. Supports layer mask filtering. Works for both 3D and 2D triggers.
// Configure a trigger-based detector in the Inspector
[SerializeReference] [JungleClassSelection]
private IDetectionStrategy detection = new TriggerDetectionStrategy();

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.

CollisionLayerMatrix

A serializable representation of Unity's 32x32 layer collision matrix. Snapshot the current physics settings with FromPhysicsSettings() and restore them with ApplyToPhysics().