bugfix no 1

This commit is contained in:
MrTorex committed 2025-11-12 20:04:06 +03:00
1 parent 874280741c
commit dbabd847c1
1 file changed
+43 -8
@@ -19,6 +19,10 @@ namespace Code.Gameplay.Character.Controller.Abilities
private float _leanFactor; private float _leanFactor;
private float _leanSign; private float _leanSign;
private Vector3 _leanDirection; private Vector3 _leanDirection;
private Vector3 _lastWallContactPoint;
private bool _isLeaningOnWall;
private const float WallProximityThreshold = 0.6f;
public WallLeanMechanic(float maxLeanAngle, float leanSharpness, float heightScale) public WallLeanMechanic(float maxLeanAngle, float leanSharpness, float heightScale)
{ {
@@ -36,9 +40,16 @@ namespace Code.Gameplay.Character.Controller.Abilities
// Вызывается из OnMovementHit // Вызывается из OnMovementHit
public void OnWallContact(KinematicCharacterMotor motor, Vector3 wallNormal, float contactHeight) public void OnWallContact(KinematicCharacterMotor motor, Vector3 wallNormal, float contactHeight)
{ {
// Только если это действительно стена (не пол/потолок)
var dotWithUp = Vector3.Dot(wallNormal, motor.CharacterUp);
if (Mathf.Abs(dotWithUp) > 0.7f) // ~45°, можно настроить
return;
_lastWallNormal = wallNormal; _lastWallNormal = wallNormal;
_lastWallContactHeight = contactHeight; _lastWallContactHeight = contactHeight;
_lastWallContactPoint = motor.TransientPosition;
// Пересчитываем направление наклона
_leanDirection = -_lastWallNormal; _leanDirection = -_lastWallNormal;
_leanDirection = Vector3.ProjectOnPlane(_leanDirection, motor.CharacterUp).normalized; _leanDirection = Vector3.ProjectOnPlane(_leanDirection, motor.CharacterUp).normalized;
@@ -76,6 +87,8 @@ namespace Code.Gameplay.Character.Controller.Abilities
break; break;
} }
} }
_isLeaningOnWall = true;
} }
// Обновление каждый кадр // Обновление каждый кадр
@@ -84,14 +97,35 @@ namespace Code.Gameplay.Character.Controller.Abilities
if (!_characterTransform) return; if (!_characterTransform) return;
var isGrounded = motor.GroundingStatus.IsStableOnGround; var isGrounded = motor.GroundingStatus.IsStableOnGround;
var currentPosition = motor.TransientPosition;
if (!isGrounded) var isStillNearWall = false;
if (_isLeaningOnWall && _lastWallNormal != Vector3.zero)
{ {
var heightDelta = motor.TransientPosition.y - _lastWallContactHeight; var toWall = currentPosition - _lastWallContactPoint;
var targetLeanFactor = Mathf.Clamp01(heightDelta * _heightScale); var distanceToWallPlane = Mathf.Abs(Vector3.Dot(toWall, _lastWallNormal));
_leanFactor = Mathf.Lerp(_leanFactor, targetLeanFactor, 1f - Mathf.Exp(-_leanSharpness * deltaTime)); isStillNearWall = distanceToWallPlane <= WallProximityThreshold;
} }
else
if (_isLeaningOnWall)
{
switch (isGrounded)
{
case true when !isStillNearWall:
case false when !isStillNearWall:
_isLeaningOnWall = false;
break;
default:
{
var heightDelta = currentPosition.y - _lastWallContactHeight;
var targetLeanFactor = Mathf.Clamp01(heightDelta * _heightScale);
_leanFactor = Mathf.Lerp(_leanFactor, targetLeanFactor, 1f - Mathf.Exp(-_leanSharpness * deltaTime));
break;
}
}
}
if (!_isLeaningOnWall)
{ {
_leanFactor = Mathf.Lerp(_leanFactor, 0f, 1f - Mathf.Exp(-_leanSharpness * deltaTime)); _leanFactor = Mathf.Lerp(_leanFactor, 0f, 1f - Mathf.Exp(-_leanSharpness * deltaTime));
} }
@@ -108,9 +142,10 @@ namespace Code.Gameplay.Character.Controller.Abilities
} }
if (_leanDirection.sqrMagnitude < 0.01f) return; if (_leanDirection.sqrMagnitude < 0.01f) return;
var leanAngle = _leanSign * _leanFactor * _maxLeanAngle; var leanAngle = _leanSign * _leanFactor * _maxLeanAngle;
var leanRotation = Quaternion.AngleAxis(leanAngle, Vector3.Cross(motor.CharacterUp, _leanDirection)); var leanAxis = Vector3.Cross(motor.CharacterUp, _leanDirection);
var leanRotation = Quaternion.AngleAxis(leanAngle, leanAxis);
_characterTransform.localRotation = leanRotation; _characterTransform.localRotation = leanRotation;
} }
} }