using _Project.Scripts.Utilities; using UnityEngine; namespace _Project.Scripts.PlayerUtils { public class PlayerMovement : MonoSingleton { [Header("Камера и Мышь")] [SerializeField] private Transform cameraPosition; [SerializeField] private float mouseSensitivity = 0.1f; [SerializeField] private float maxLookAngle = 80f; [Header("Скорости передвижения (м/с)")] [SerializeField] private float moveSpeed = 6.5f; // Обычный бег (~250 u/s) [SerializeField] private float sprintSpeed = 9.5f; // Спринт (~360 u/s) [SerializeField] private float crouchSpeed = 3f; [Header("Параметры Подката (Slide)")] [Tooltip("Начальная взрывная скорость подката")] [SerializeField] private float slideInitialSpeed = 15f; // (~580 u/s) [Tooltip("Длительность скольжения в секундах")] [SerializeField] private float slideDuration = 0.85f; [Tooltip("Трение коленей при подкате")] [SerializeField] private float slideFriction = 2.8f; [Tooltip("Наклон камеры набок при подкате (градусы)")] [SerializeField] private float slideCameraTiltAngle = 4f; [SerializeField] private float slideCooldown = 0.35f; [Header("Физика CS / Source (Bunnyhop & Strafe)")] [Tooltip("Трение на земле (гасит скорость, если не успели прыгнуть вовремя)")] [SerializeField] private float groundFriction = 5f; [Tooltip("Ускорение на земле")] [SerializeField] private float groundAcceleration = 10f; [Tooltip("Сила набора скорости в воздухе при стрейфах (sv_airaccelerate)")] [SerializeField] private float airAcceleration = 80f; [Tooltip("Лимит добавления скорости в воздухе")] [SerializeField] private float airCap = 2.0f; [Tooltip("Показывать спидометр на экране")] [SerializeField] private bool showSpeedometer = true; [Header("Гравитация и Прыжок")] [SerializeField] private float jumpHeight = 1.35f; [SerializeField] private float gravity = -25f; [SerializeField] private float fallMultiplier = 1.8f; [SerializeField] private LayerMask groundLayer; [SerializeField] private float groundCheckDistance = 0.12f; [Tooltip("Буфер прыжка (время поблажки для колесика мыши)")] [SerializeField] private float jumpBufferTime = 0.12f; [Header("Параметры приседания")] [SerializeField] private float standingHeight = 2f; [SerializeField] private float crouchingHeight = 1.05f; [SerializeField] private float standingCameraY = 1.6f; [SerializeField] private float crouchingCameraY = 0.8f; [SerializeField] private float crouchTransitionSpeed = 15f; private Rigidbody rb; private CapsuleCollider col; private Vector2 moveInput; private Vector2 lookInput; private Vector3 horizontalVelocity = Vector3.zero; private float verticalVelocity = 0f; private bool isGrounded; private bool wasGrounded; private bool isSprinting = false; private bool isCrouching = false; private float jumpBufferTimer = 0f; // Подкат private bool isSliding = false; private float slideTimer = 0f; private float slideCurrentSpeed = 0f; private Vector3 slideDirection = Vector3.zero; private float slideCooldownTimer = 0f; private PlayerControls controls; void Awake() { base.Awake(); rb = GetComponent(); col = GetComponent(); mouseSensitivity = PlayerPrefs.GetFloat("MouseSensitivity", mouseSensitivity); rb.useGravity = false; rb.freezeRotation = true; rb.interpolation = RigidbodyInterpolation.None; controls = new PlayerControls(); controls = Player.Instance.controls; // Спринт controls.Player.Sprint.started += ctx => isSprinting = true; controls.Player.Sprint.canceled += ctx => isSprinting = false; /* // Присед и Подкат controls.Player.Crouch.started += ctx => OnCrouchPressed(); controls.Player.Crouch.canceled += ctx => OnCrouchReleased(); // Прыжок на Пробел (через буфер) controls.Player.Jump.performed += ctx => QueueJump(); */ } } }