Risk of Rain 2
Install with App

Details

Latest version
4.0.0
Last Updated
First Uploaded
Downloads
542
Likes
1
Size
102KB
Dependants

Mod Description:

What Mod Creator has to say: "During 60 lemurians tests I get on average 20% more fps. Some code could be put under jobs further more"

Rundown on what Gemini 4 Argon did for optimizing:

KinematicCharacterController — Burst & Job System Rewrite

A high-performance, zero-allocation drop-in replacement for KinematicCharacterController.dll targeting Unity 2021.3.45f2 (Risk of Rain 2). This rewrite replaces the original single-threaded, recursive managed physics loops with a multi-threaded Unity C# Job System + Burst + PhysX Batch Command pipeline while maintaining 100% Public & Private ABI compatibility.

Key Architectural Changes

1. 5-Phase Batched Simulation Pipeline

Instead of simulating each KinematicCharacterMotor individually on the main thread with dozens of synchronous Physics.CapsuleCastNonAlloc and Physics.OverlapCapsuleNonAlloc calls per motor, KinematicCharacterSystem now processes all active motors in a unified 5-phase batch pipeline:

  1. Phase 1 — Managed Gather & State Pack (GatherAndPackJobData):
    • Fires ICharacterController.BeforeCharacterUpdate, UpdateRotation, and UpdateVelocity in exact lifecycle order.
    • Performs a single-pass OverlapCapsuleNonAlloc + Physics.ComputePenetration check only for actively moving motors (idle motors skip overlap checks completely).
    • Packs motor state into a flat, blittable NativeArray<MotorJobData> (LayoutKind.Sequential) and temporarily disables each motor's own CapsuleCollider so batch queries never self-intersect.
  2. Phase 2 — Burst Command Preparation (PreparePhysicsCommandsJob):
    • Runs as a Burst-compiled IJobParallelFor (FloatMode.Fast, OptimizeFor.Performance).
    • Computes character basis vectors (CharacterUp, CharacterForward, CharacterRight), combines root motion (MoveCharacter) with BaseVelocity and AttachedRigidbodyVelocity, applies overlap and planar constraints, and populates NativeArray<CapsulecastCommand>, NativeArray<RaycastCommand>, and NativeArray<SpherecastCommand>.
  3. Phase 3 — Native PhysX Batch Queries (ScheduleBatch):
    • Dispatches primary movement sweeps (CapsulecastCommand.ScheduleBatch), step-check rays (RaycastCommand.ScheduleBatch), and ground probes (SpherecastCommand.ScheduleBatch) across Unity's native job worker threads.
    • Runs PrepareSecondaryCommandsJob (IJobParallelFor) to build a second deflected CapsulecastCommand only for motors that hit a blocking surface in Sub-step 1, plus post-movement ground SpherecastCommand and center fallback RaycastCommand batches at the predicted final position.
  4. Phase 4 — Burst Movement & Grounding Solver (SolveCharacterMovementJob):
    • Runs as a Burst-compiled IJobParallelFor using Unity.Mathematics SIMD types (float3, quaternion, math.*).
    • Resolves sub-step movement, fast step-up snapping, slope/crease velocity deflection, and slope-compensated ground snapping without touching managed memory.
  5. Phase 5 — Managed Writeback & Callbacks (ApplyBatchWritebackAndCallbacks):
    • Unpacks solved positions, rotations, velocities, and CharacterGroundingReport states back to each KinematicCharacterMotor.
    • Resolves hit Collider instances via a fast InstanceID cache and fires ProcessHitStabilityReport, OnMovementHit, OnGroundHit, PostGroundingUpdate, and AfterCharacterUpdate in their exact original order.

Performance Optimizations & Algorithmic Simplifications

Area Original KCC Burst Rewrite
Movement Sub-stepping Up to 6–8 recursive sweep iterations per motor per tick (while (remainingMovementMagnitude > 0 && num <= 6)) Hard-capped at max 2 sub-steps (1 primary sweep + 1 deflected sweep only on collision)
Ground Probing Iterative capsule sweeps (while (num <= 2)) + dual inner/outer raycasts (EvaluateHitStability) Single post-move inset SpherecastCommand + center RaycastCommand fallback
Step Handling Multi-hit capsule sweeps + vertical downward step-landing sweeps + dual stability raycasts Single elevated forward RaycastCommand at MaxStepHeight
Depenetration Up to 3 full OverlapCapsule + ComputePenetration loops twice per tick (Phase 1 & Phase 2), even when idle Bypassed when idle; single-pass direct normal push only when moving
PhysicsMover Multi-point kinematic sweep & depenetration transfer Simplified linear & angular velocity delta provider
Memory & GC Per-motor managed arrays and repeated struct copies Persistent NativeArray<T> pools allocated once (Allocator.Persistent) and resized only when motor count exceeds capacity (0 bytes GC per tick)

Physics & Gameplay Fidelity Improvements

  • Full Slope Speed Preservation:
    • HandleVelocityProjection projects grounded movement along GetDirectionTangentToSurface using full 3D velocity magnitude rather than horizontal planar magnitude, eliminating $\cos^2\theta$ speed loss on steep walkable ramps.
    • Re-projects BaseVelocity in ProbeGround only on airborne-to-grounded transitions (!WasStableOnGround && IsStableOnGround).
  • Steep Slope & Cliff Climb Prevention:
    • Grounded collisions against unstable slopes (angle > MaxStableSlopeAngle) deflect horizontally around the obstruction first and then align onto GroundNormal, preventing horizontal velocity from converting into upward $+Y$ climb.
    • Airborne collisions against unstable slopes split horizontal and vertical components so horizontal pushing never lifts the motor up steep cliffs while downward velocity slides down the slope.
    • Rejects false-positive edge stability on steep polygon seams by verifying the vertical contact offset on the probe hemisphere at impact.
  • Smooth Root Motion & Anti-Clipping on Angled Surfaces:
    • Composes Animator rootMotion (MoveCharacter) with BaseVelocity and AttachedRigidbodyVelocity without overwriting gravity or knockback velocity.
    • Preserves root-motion displacement across Phase 1 depenetration so depenetration pushes never cancel out root motion.
    • Enforces minimum perpendicular surface clearance (neededPerp) and a $+2\text{ mm}$ normal offset before Sub-step 2 so grazing root-motion sweeps never wedge into angled surfaces.
    • Handles initial-overlap cast hits (hit.colliderInstanceID != 0 && hit.distance == 0f) as blocked collisions rather than unobstructed movement, preventing clipping through geometry.
    • Uses a radially inset ground SpherecastCommand (CapsuleRadius - CollisionOffset) with exact trigonometric slope compensation (colOffset / cos(slopeAngle)) paired with a center downward RaycastCommand fallback, preventing ground loss and vertical jitter when pushing against angled walls, rocks, or overhangs.
Thunderstore development is made possible with ads. Please consider making an exception to your adblock.