fix ducking modifying body height, stomping over user changes (#3463)

This commit is contained in:
Layla
2025-11-29 11:16:50 +00:00
committed by GitHub
parent bc133aba24
commit 16809db787
7 changed files with 21 additions and 26 deletions

View File

@@ -102,7 +102,7 @@ public partial class MoveModeLadder : MoveMode
return;
var wt = WorldTransform;
Vector3 head = wt.PointToWorld( new Vector3( 0, 0, Controller.BodyHeight ) );
Vector3 head = wt.PointToWorld( new Vector3( 0, 0, Controller.CurrentHeight ) );
Vector3 foot = wt.Position;
GameObject ladderObject = default;

View File

@@ -9,7 +9,7 @@ partial class MoveMode
public virtual Transform CalculateEyeTransform()
{
var transform = new Transform();
transform.Position = Controller.WorldPosition + Vector3.Up * (Controller.BodyHeight - Controller.EyeDistanceFromTop);
transform.Position = Controller.WorldPosition + Vector3.Up * (Controller.CurrentHeight - Controller.EyeDistanceFromTop);
transform.Rotation = Controller.EyeAngles.ToRotation();
return transform;
}

View File

@@ -57,7 +57,7 @@ public partial class MoveModeSwim : MoveMode
return;
var wt = WorldTransform;
Vector3 head = wt.PointToWorld( new Vector3( 0, 0, Controller.BodyHeight ) );
Vector3 head = wt.PointToWorld( new Vector3( 0, 0, Controller.CurrentHeight ) );
Vector3 foot = wt.Position;
float waterLevel = 0;

View File

@@ -86,7 +86,7 @@ public sealed partial class PlayerController : Component
void UpdateHeadroom()
{
var tr = TraceBody( WorldPosition + Vector3.Up * BodyHeight * 0.5f, WorldPosition + Vector3.Up * (100 + BodyHeight * 0.5f), 0.75f, 0.5f );
var tr = TraceBody( WorldPosition + Vector3.Up * CurrentHeight * 0.5f, WorldPosition + Vector3.Up * (100 + CurrentHeight * 0.5f), 0.75f, 0.5f );
Headroom = tr.Distance;
}

View File

@@ -43,7 +43,7 @@ public sealed partial class PlayerController : Component
/// </summary>
void UpdateBody()
{
var feetHeight = BodyHeight * 0.5f;
var feetHeight = CurrentHeight * 0.5f;
var radius = (BodyRadius * MathF.Sqrt( 2 )) / 2;
// If we're not on the ground, we have slippy as fuck feet
@@ -77,12 +77,12 @@ public sealed partial class PlayerController : Component
// If it becomes too short to fit, disable it and let the feet collider cover the rest.
//
BodyCollider.Radius = radius;
BodyCollider.Start = Vector3.Up * (BodyHeight - radius);
BodyCollider.Start = Vector3.Up * (CurrentHeight - radius);
BodyCollider.End = Vector3.Up * MathF.Max( BodyCollider.Start.z - (feetHeight - radius), radius + 1.0f );
BodyCollider.Friction = 0.0f;
BodyCollider.Enabled = BodyCollider.End.z < BodyCollider.Start.z;
FeetCollider.Scale = new Vector3( BodyRadius, BodyRadius, BodyCollider.Enabled ? feetHeight : BodyHeight );
FeetCollider.Scale = new Vector3( BodyRadius, BodyRadius, BodyCollider.Enabled ? feetHeight : CurrentHeight );
FeetCollider.Center = new Vector3( 0, 0, FeetCollider.Scale.z * 0.5f );
FeetCollider.Friction = feetFriction;
FeetCollider.Enabled = true;
@@ -99,7 +99,7 @@ public sealed partial class PlayerController : Component
// When trying to move, we move the mass center up to the waist so the player can "step" over smaller shit
// When not moving we drop it to the foot position.
//
float massCenter = IsOnGround ? WishVelocity.Length.Clamp( 0, BodyHeight * 0.5f ) : BodyHeight * 0.5f;
float massCenter = IsOnGround ? WishVelocity.Length.Clamp( 0, CurrentHeight * 0.5f ) : CurrentHeight * 0.5f;
Body.MassCenterOverride = new Vector3( 0, 0, massCenter );
Body.OverrideMassCenter = true;

View File

@@ -111,9 +111,14 @@ public sealed partial class PlayerController : Component
}
}
float unduckedHeight = -1;
Vector3 bodyDuckOffset = 0;
/// <summary>
/// Gets the current character height from <see cref="BodyHeight"/> when standing,
/// otherwise uses <see cref="DuckedHeight"/> when ducking.
/// </summary>
public float CurrentHeight => IsDucking ? DuckedHeight : BodyHeight;
/// <summary>
/// Called during FixedUpdate when UseInputControls is enabled. Will duck if requested.
/// If not, and we're ducked, will unduck if there is room
@@ -122,8 +127,7 @@ public sealed partial class PlayerController : Component
{
if ( wantsDuck == IsDucking ) return;
unduckedHeight = MathF.Max( unduckedHeight, BodyHeight );
var unduckDelta = unduckedHeight - DuckedHeight;
var unduckDelta = CurrentHeight - DuckedHeight;
// Can we unduck?
if ( !wantsDuck )
@@ -137,21 +141,12 @@ public sealed partial class PlayerController : Component
IsDucking = wantsDuck;
if ( wantsDuck )
// if we're in the air, keep our head in the same position
if ( wantsDuck && IsAirborne )
{
BodyHeight = DuckedHeight;
// if we're in the air, keep our head in the same position
if ( IsAirborne )
{
WorldPosition += Vector3.Up * unduckDelta;
Transform.ClearInterpolation();
bodyDuckOffset = Vector3.Up * -unduckDelta;
}
}
else
{
BodyHeight = unduckedHeight;
WorldPosition += Vector3.Up * unduckDelta;
Transform.ClearInterpolation();
bodyDuckOffset = Vector3.Up * -unduckDelta;
}
}
}

View File

@@ -5,7 +5,7 @@ public sealed partial class PlayerController : Component
/// <summary>
/// Return an aabb representing the body
/// </summary>
public BBox BodyBox( float scale = 1.0f, float heightScale = 1.0f ) => new BBox( new Vector3( -BodyRadius * 0.5f * scale, -BodyRadius * 0.5f * scale, 0 ), new Vector3( BodyRadius * 0.5f * scale, BodyRadius * 0.5f * scale, BodyHeight * heightScale ) );
public BBox BodyBox( float scale = 1.0f, float heightScale = 1.0f ) => new BBox( new Vector3( -BodyRadius * 0.5f * scale, -BodyRadius * 0.5f * scale, 0 ), new Vector3( BodyRadius * 0.5f * scale, BodyRadius * 0.5f * scale, CurrentHeight * heightScale ) );
/// <summary>
/// Trace the aabb body from one position to another and return the result