From c58a17b8af38f6742ead2d0a2752809bcecfadf8 Mon Sep 17 00:00:00 2001 From: Luis Gonzalez Date: Thu, 9 Jul 2026 20:06:05 -0700 Subject: [PATCH] =?UTF-8?q?Fix:=20planar=20Y-lock=20in=20CharacterProcesso?= =?UTF-8?q?r=20=E2=80=94=20no=20more=20climbing/floating=20on=20sloped=20c?= =?UTF-8?q?olliders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Field report: walking onto hilly-looking colliders (the new convex rock hulls are ramps) raised the character's Y, and with gravity zero + SnapToGround off nothing ever brought it back down - the character floated and its shadow drifted away. Fix inside CharacterProcessor.PhysicsUpdate: capture the pre-update Y and restore it (plus zero RelativeVelocity.y) after the CC sequence - the character update itself can never change the movement plane, while spawn/teleport writes made outside the update stay honored. Deterministic + idempotent (rollback-safe), identical on server + predicted client. Verified live: player shoved into a cover-hull sloped edge decollided ~1 u horizontally with Y bit-exact at 1.0000 (the case that previously rode up the slope); 466/466 EditMode, console clean. Co-Authored-By: Claude Fable 5 --- .../Scripts/Simulation/Player/CharacterProcessor.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Assets/_Project/Scripts/Simulation/Player/CharacterProcessor.cs b/Assets/_Project/Scripts/Simulation/Player/CharacterProcessor.cs index 08b867f31..3862b41d4 100644 --- a/Assets/_Project/Scripts/Simulation/Player/CharacterProcessor.cs +++ b/Assets/_Project/Scripts/Simulation/Player/CharacterProcessor.cs @@ -34,6 +34,7 @@ namespace ProjectM.Simulation ref CharacterComponent characterComponent = ref CharacterComponent.ValueRW; ref KinematicCharacterBody characterBody = ref CharacterDataAccess.CharacterBody.ValueRW; ref float3 characterPosition = ref CharacterDataAccess.LocalTransform.ValueRW.Position; + float planeY = characterPosition.y; // authored movement plane — restored after the update (see below) KinematicCharacterUtilities.Update_Initialize( in this, ref context, ref baseContext, @@ -100,6 +101,14 @@ namespace ProjectM.Simulation KinematicCharacterUtilities.Update_ProcessStatefulCharacterHits( CharacterDataAccess.CharacterHitsBuffer, CharacterDataAccess.StatefulHitsBuffer); + + // Top-down planar lock: the world is one flat plane and gravity is zero, so any Y gained by + // step-handling/velocity-projection up a sloped collider (convex rock hulls etc.) would persist + // FOREVER — the character ends up floating and its shadow drifts away (07-09 field report). + // Restoring the pre-update Y forbids the CC update itself from ever changing the plane while + // spawn/teleport writes (made outside this update) stay honored. Deterministic + idempotent. + characterPosition.y = planeY; + characterBody.RelativeVelocity.y = 0f; } void HandleVelocityControl(ref CharacterUpdateContext context, ref KinematicCharacterUpdateContext baseContext)