Сглаживание бега

This commit is contained in:
2025-01-28 10:32:19 +03:00
parent 267ebc6fe5
commit 305f83a924
2 changed files with 8 additions and 1 deletions

View File

@ -0,0 +1,134 @@
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
public class SwingingArmMotionScript : MonoBehaviour
{
// Game Objects
[SerializeField] private GameObject LeftHand;
[SerializeField] private GameObject RightHand;
[SerializeField] private GameObject MainCamera;
[SerializeField] private ActionBasedContinuousMoveProvider _MoveProvider;
// Vector3 Positions
[SerializeField] private Vector3 PositionPreviousFrameLeftHand;
[SerializeField] private Vector3 PositionPreviousFrameRightHand;
[SerializeField] private Vector3 PlayerPositionPreviousFrame;
[SerializeField] private Vector3 PlayerPositionCurrentFrame;
[SerializeField] private Vector3 PositionCurrentFrameLeftHand;
[SerializeField] private Vector3 PositionCurrentFrameRightHand;
// Speed
[SerializeField] private float BaseSpeed; // Базовая скорость
[SerializeField] private float SprintSpeedMultiplier; // Множитель для бега
[SerializeField] private float HandSpeedThreshold; // Порог скорости рук для бега
private float CurrentSpeed; // Текущая скорость
[SerializeField] private float HandSpeed;
private float SmoothedSpeed;
[SerializeField] private float SpeedSmoothingFactor;
// Stamina (выносливость)
[SerializeField] private float MaxStamina; // Максимальная выносливость
[SerializeField] private float Stamina; // Текущая выносливость
[SerializeField] private float StaminaDrainRate; // Скорость расхода выносливости (единиц/сек)
[SerializeField] private float StaminaRecoveryRate; // Скорость восстановления (единиц/сек)
[SerializeField] private float LowStaminaMultiplier; // Снижение скорости при низкой выносливости
[SerializeField] private float StaminaRecoveryDelay; // Задержка перед восстановлением после израсходования
[SerializeField] private bool IsRecovering = false; // Флаг для ожидания восстановления
[SerializeField] private float RecoveryTimer; // Таймер восстановления
[SerializeField] private bool IsPreRecovery = false;
void Start()
{
BaseSpeed = _MoveProvider.moveSpeed;
PlayerPositionPreviousFrame = transform.position; // Set current positions
PositionPreviousFrameLeftHand = LeftHand.transform.position; // Set previous positions
PositionPreviousFrameRightHand = RightHand.transform.position;
CurrentSpeed = BaseSpeed; // Initialize to base speed
SmoothedSpeed = BaseSpeed;
Stamina = MaxStamina; // Инициализация выносливости
}
// Update is called once per frame
void Update()
{
// Get positions of hands
PositionCurrentFrameLeftHand = LeftHand.transform.position;
PositionCurrentFrameRightHand = RightHand.transform.position;
// Position of player
PlayerPositionCurrentFrame = transform.position;
// Get distance the hands and player has moved from last frame
var playerDistanceMoved = Vector3.Distance(PlayerPositionCurrentFrame, PlayerPositionPreviousFrame);
var leftHandDistanceMoved = Vector3.Distance(PositionPreviousFrameLeftHand, PositionCurrentFrameLeftHand);
var rightHandDistanceMoved = Vector3.Distance(PositionPreviousFrameRightHand, PositionCurrentFrameRightHand);
// Aggregate to get hand speed
HandSpeed = ((leftHandDistanceMoved - playerDistanceMoved) + (rightHandDistanceMoved - playerDistanceMoved));
if (IsRecovering)
{
RecoveryTimer += Time.deltaTime;
if (RecoveryTimer >= StaminaRecoveryDelay)
{
IsRecovering = false;
RecoveryTimer = 0;
}
if (HandSpeed > HandSpeedThreshold)
{
CurrentSpeed = BaseSpeed; // Замедляем, если стамина истощена
RecoveryTimer = 0;
}
}
if (!IsRecovering)
{
Stamina += StaminaRecoveryRate * Time.deltaTime; // Восстанавливаем стамину
Stamina = Mathf.Clamp(Stamina, 0, MaxStamina);
if (IsPreRecovery)
{
if (Stamina >= 0.5*MaxStamina)
{
IsPreRecovery = false;
}
}
if (HandSpeed > HandSpeedThreshold)
{
Stamina -= StaminaDrainRate * Time.deltaTime; // Уменьшаем стамину
Stamina = Mathf.Clamp(Stamina, 0, MaxStamina);
if (!IsPreRecovery)
{
CurrentSpeed = BaseSpeed * SprintSpeedMultiplier; // Замедляем, если стамина истощена
}
else if (IsPreRecovery)
{
CurrentSpeed = BaseSpeed;
}
}
else
{
CurrentSpeed = BaseSpeed;
}
}
if (Stamina <= 0)
{
IsRecovering = true;
IsPreRecovery = true;
}
SmoothedSpeed = Mathf.Lerp(SmoothedSpeed, CurrentSpeed, SpeedSmoothingFactor);
_MoveProvider.moveSpeed = SmoothedSpeed;
// Set previous position of hands for next frame
PositionPreviousFrameLeftHand = PositionCurrentFrameLeftHand;
PositionPreviousFrameRightHand = PositionCurrentFrameRightHand;
// Set player position previous frame
PlayerPositionPreviousFrame = PlayerPositionCurrentFrame;
}
}