148 lines
6.1 KiB
C#
148 lines
6.1 KiB
C#
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; // Максимальная выносливость
|
||
public float MaxStamina
|
||
{
|
||
get { return _MaxStamina; }
|
||
}
|
||
|
||
[SerializeField] private float _Stamina; // Текущая выносливость
|
||
public float Stamina
|
||
{
|
||
get { return _Stamina; }
|
||
set { _Stamina = value; }
|
||
}
|
||
[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;
|
||
public bool IsPreRecovery
|
||
{
|
||
get { return _IsPreRecovery; }
|
||
}
|
||
|
||
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;
|
||
}
|
||
} |