Crossy_Road_VR/Assets/Crossy Road VR/Scripts/SwingingArmMotionScript.cs

134 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}