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 _leanSign;
private Vector3 _leanDirection;
private Vector3 _lastWallContactPoint;
private bool _isLeaningOnWall;
private const float WallProximityThreshold = 0.6f;
public WallLeanMechanic(float maxLeanAngle, float leanSharpness, float heightScale)
{
@@ -36,9 +40,16 @@ namespace Code.Gameplay.Character.Controller.Abilities
// Вызывается из OnMovementHit
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;
_lastWallContactHeight = contactHeight;
_lastWallContactPoint = motor.TransientPosition;
// Пересчитываем направление наклона
_leanDirection = -_lastWallNormal;
_leanDirection = Vector3.ProjectOnPlane(_leanDirection, motor.CharacterUp).normalized;
@@ -76,6 +87,8 @@ namespace Code.Gameplay.Character.Controller.Abilities
break;
}
}
_isLeaningOnWall = true;
}
// Обновление каждый кадр
@@ -84,14 +97,35 @@ namespace Code.Gameplay.Character.Controller.Abilities
if (!_characterTransform) return;
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 targetLeanFactor = Mathf.Clamp01(heightDelta * _heightScale);
_leanFactor = Mathf.Lerp(_leanFactor, targetLeanFactor, 1f - Mathf.Exp(-_leanSharpness * deltaTime));
var toWall = currentPosition - _lastWallContactPoint;
var distanceToWallPlane = Mathf.Abs(Vector3.Dot(toWall, _lastWallNormal));
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));
}
@@ -108,9 +142,10 @@ namespace Code.Gameplay.Character.Controller.Abilities
}
if (_leanDirection.sqrMagnitude < 0.01f) return;
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;
}
}