Плавность это круто

This commit is contained in:
MrTorex committed 2025-12-04 21:44:11 +03:00
1 parent ecff1e69cd
commit 6732aef384
1 file changed
+108 -35
@@ -30,6 +30,14 @@ namespace Code.Gameplay.Character.Controller
private Vector3 _originalColliderCenter; private Vector3 _originalColliderCenter;
private float _originalColliderHeight; private float _originalColliderHeight;
private Vector3 _originalFollowPointLocalPosition; private Vector3 _originalFollowPointLocalPosition;
private bool _isEnteringSlide;
private bool _isExitingSlide;
private float _slideTransitionTime;
private float _slideTransitionDuration;
private float _currentColliderHeight;
private Vector3 _currentColliderCenter;
private Vector3 _currentFollowPointLocalPosition;
private bool _wasSlidingLastFrame;
// Подсистемы // Подсистемы
private CharacterInputHandler _inputHandler; private CharacterInputHandler _inputHandler;
@@ -99,16 +107,13 @@ namespace Code.Gameplay.Character.Controller
_wallLeanMechanic.SetModel(characterTransform); _wallLeanMechanic.SetModel(characterTransform);
_wallRunningMechanic.Initialize(motor); _wallRunningMechanic.Initialize(motor);
if (_capsuleCollider != null)
{
_originalColliderCenter = _capsuleCollider.center; _originalColliderCenter = _capsuleCollider.center;
_originalColliderHeight = _capsuleCollider.height; _originalColliderHeight = _capsuleCollider.height;
}
if (_cameraFollowPoint != null)
{
_originalFollowPointLocalPosition = _cameraFollowPoint.localPosition; _originalFollowPointLocalPosition = _cameraFollowPoint.localPosition;
}
_currentColliderHeight = _originalColliderHeight;
_currentColliderCenter = _originalColliderCenter;
_currentFollowPointLocalPosition = _originalFollowPointLocalPosition;
} }
// Текущий режим камеры для адаптации поведения // Текущий режим камеры для адаптации поведения
@@ -201,28 +206,31 @@ namespace Code.Gameplay.Character.Controller
return; return;
} }
if (!_slideMechanic.IsSliding) var wasSliding = _wasSlidingLastFrame;
var isSlidingNow = _slideMechanic.IsSliding;
if (!isSlidingNow)
{ {
_slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation, _inputHandler.LookInputVector); _slideMechanic.TryStartSlide(motor, _currentCameraMode, _inputHandler.FirstPersonCameraRotation, _inputHandler.LookInputVector);
isSlidingNow = _slideMechanic.IsSliding;
}
if (_slideMechanic.IsSliding) switch (isSlidingNow)
{ {
case true when !wasSliding:
EnterSlideState(); EnterSlideState();
} break;
else case false when wasSliding:
{
ExitSlideState(); ExitSlideState();
break;
} }
}
else if (isSlidingNow)
{ {
_slideMechanic.HandleSlide(ref currentVelocity, deltaTime, motor); _slideMechanic.HandleSlide(ref currentVelocity, deltaTime, motor);
}
if (!_slideMechanic.IsSliding) _wasSlidingLastFrame = isSlidingNow;
{
ExitSlideState();
}
}
// === WALL RUNNING: обработка состояния === // === WALL RUNNING: обработка состояния ===
if (_wallRunningMechanic.IsWallRunning) if (_wallRunningMechanic.IsWallRunning)
@@ -261,37 +269,100 @@ namespace Code.Gameplay.Character.Controller
private void EnterSlideState() private void EnterSlideState()
{ {
if (_capsuleCollider) _isEnteringSlide = true;
{ _isExitingSlide = false;
var newHeight = _originalColliderHeight * _characterConfig.slideColliderHeightScale; _slideTransitionTime = 0f;
_slideTransitionDuration = _characterConfig.slideEnterDuration;
_capsuleCollider.height = newHeight;
var newCenterY = newHeight * 0.5f - _originalColliderHeight * 0.5f;
_capsuleCollider.center = _originalColliderCenter + Vector3.up * newCenterY;
}
if (!_cameraFollowPoint) return;
var offset = Vector3.up * _characterConfig.slideCameraOffsetY;
_cameraFollowPoint.localPosition = _originalFollowPointLocalPosition + offset;
} }
private void ExitSlideState() private void ExitSlideState()
{ {
_isExitingSlide = true;
_isEnteringSlide = false;
_slideTransitionTime = 0f;
_slideTransitionDuration = _characterConfig.slideExitDuration;
}
private void UpdateSlideTransition(float deltaTime)
{
if (!_isEnteringSlide && !_isExitingSlide) return;
_slideTransitionTime += deltaTime;
var t = Mathf.Clamp01(_slideTransitionTime / _slideTransitionDuration);
t = Mathf.SmoothStep(0f, 1f, t);
if (_isEnteringSlide)
{
var targetHeight = _originalColliderHeight * _characterConfig.slideColliderHeightScale;
var targetCenterY = targetHeight * 0.5f - _originalColliderHeight * 0.5f;
var targetCenter = _originalColliderCenter + Vector3.up * targetCenterY;
var targetFollowPos = _originalFollowPointLocalPosition + Vector3.up * _characterConfig.slideCameraOffsetY;
_currentColliderHeight = Mathf.Lerp(_originalColliderHeight, targetHeight, t);
_currentColliderCenter = Vector3.Lerp(_originalColliderCenter, targetCenter, t);
_currentFollowPointLocalPosition = Vector3.Lerp(_originalFollowPointLocalPosition, targetFollowPos, t);
}
else if (_isExitingSlide)
{
_currentColliderHeight = Mathf.Lerp(_originalColliderHeight * _characterConfig.slideColliderHeightScale, _originalColliderHeight, t);
var prevHeight = _originalColliderHeight * _characterConfig.slideColliderHeightScale;
var prevCenterY = prevHeight * 0.5f - _originalColliderHeight * 0.5f;
var prevCenter = _originalColliderCenter + Vector3.up * prevCenterY;
var prevFollowPos = _originalFollowPointLocalPosition + Vector3.up * _characterConfig.slideCameraOffsetY;
_currentColliderCenter = Vector3.Lerp(prevCenter, _originalColliderCenter, t);
_currentFollowPointLocalPosition = Vector3.Lerp(prevFollowPos, _originalFollowPointLocalPosition, t);
}
if (_capsuleCollider)
{
_capsuleCollider.height = _currentColliderHeight;
_capsuleCollider.center = _currentColliderCenter;
}
if (_cameraFollowPoint)
{
_cameraFollowPoint.localPosition = _currentFollowPointLocalPosition;
}
if (!(t >= 1f)) return;
if (_isEnteringSlide)
{
_isEnteringSlide = false;
if (_capsuleCollider)
{
_capsuleCollider.height = _originalColliderHeight * _characterConfig.slideColliderHeightScale;
var h = _capsuleCollider.height;
_capsuleCollider.center = _originalColliderCenter + Vector3.up * (h * 0.5f - _originalColliderHeight * 0.5f);
}
if (_cameraFollowPoint)
{
_cameraFollowPoint.localPosition = _originalFollowPointLocalPosition + Vector3.up * _characterConfig.slideCameraOffsetY;
}
}
else if (_isExitingSlide)
{
_isExitingSlide = false;
if (_capsuleCollider) if (_capsuleCollider)
{ {
_capsuleCollider.height = _originalColliderHeight; _capsuleCollider.height = _originalColliderHeight;
_capsuleCollider.center = _originalColliderCenter; _capsuleCollider.center = _originalColliderCenter;
} }
if (_cameraFollowPoint) if (_cameraFollowPoint)
{ {
_cameraFollowPoint.localPosition = _originalFollowPointLocalPosition; _cameraFollowPoint.localPosition = _originalFollowPointLocalPosition;
} }
} }
_currentColliderHeight = _capsuleCollider ? _capsuleCollider.height : _originalColliderHeight;
_currentColliderCenter = _capsuleCollider ? _capsuleCollider.center : _originalColliderCenter;
_currentFollowPointLocalPosition = _cameraFollowPoint ? _cameraFollowPoint.localPosition : _originalFollowPointLocalPosition;
}
public void BeforeCharacterUpdate(float deltaTime) public void BeforeCharacterUpdate(float deltaTime)
{ {
@@ -307,6 +378,8 @@ namespace Code.Gameplay.Character.Controller
public void AfterCharacterUpdate(float deltaTime) public void AfterCharacterUpdate(float deltaTime)
{ {
UpdateSlideTransition(deltaTime);
_wallLeanMechanic.Update( _wallLeanMechanic.Update(
_wallRunningMechanic.IsWallRunning, _wallRunningMechanic.IsWallRunning,
_wallRunningMechanic.GetWallNormal(), _wallRunningMechanic.GetWallNormal(),