Плавность это круто
This commit is contained in:
1 parent
ecff1e69cd
commit
6732aef384
1 file changed
+108
-35
+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(),
|
||||||
|
|||||||
Reference in new issue
Block a user