using UnityEngine; public class PlayerMovement : MonoBehaviour { [Header("Movement Settings")] public float mouseSensitivity = 2.0f; [Header("Movement Speeds")] public float walkSpeed = 1.4f; // Скорость ходьбы public float runSpeed = 2.5f; // Скорость бега public float crouchSpeed = 1.1f; // Скорость при приседании private float current_speed; [Header("Camera Settings")] public Camera playerCamera; // Привяжите камеру через Inspector [Header("Head Bobbing Settings")] public float bobFrequency = 1.5f; // Частота тряски public float bobHorizontalAmplitude = 0.1f; // Горизонтальная амплитуда public float bobVerticalAmplitude = 0.1f; // Вертикальная амплитуда public Vector3 originalCameraPosition; private float bobTimer = 1f; [Header("Acceleration Settings")] public float acceleration = 14f; public float deceleration = 10f; private Vector3 currentVelocity = Vector3.zero; [Header("Jump Settings")] public float jumpHeight = 1.52f; public float gravity = -30f; private float verticalVelocity = 0f; [Header("Crouch Settings")] public float crouchHeight = 1f; public float standingHeight = 2f; private bool isCrouching = false; private CharacterController controller; private float rotationX = 0f; private float rotationY = 0f; [Header("Camera Shake Settings")] public float shakeIntensity = 1f; // Интенсивность вращения public float shakeFrequency = 2.0f; // Частота вращения public float restShakeFrequency = 0.5f; // Частота вращения в состоянии покоя public float restShakeIntensity = 0.5f; // Интенсивность вращения в состоянии покоя void Start() { controller = GetComponent(); // Скрыть и заблокировать курсор Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; // Если камера не назначена, пытаемся найти ее среди дочерних объектов if (playerCamera == null) { playerCamera = GetComponentInChildren(); } if (playerCamera == null) { Debug.LogError("PlayerMovement: Камера не назначена и не найдена среди дочерних объектов."); } originalCameraPosition = playerCamera.transform.localPosition; // Сохраняем исходную позицию камеры } void Update() { if (playerCamera == null) { Debug.LogWarning("PlayerMovement: Камера не назначена."); return; } // === Управление камерой === // Получение ввода мыши float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity; float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity; rotationY += mouseX; rotationX -= mouseY; rotationX = Mathf.Clamp(rotationX, -90f, 90f); // Применение вращения к камере playerCamera.transform.localRotation = Quaternion.Euler(rotationX, 0f, 0f); // Поворот игрока по оси Y transform.rotation = Quaternion.Euler(0f, rotationY, 0f); // === Управление движением === // Обработка приседания if (Input.GetKeyDown(KeyCode.LeftControl)) { Crouch(); } else if (Input.GetKeyUp(KeyCode.LeftControl)) { StandUp(); } // Получение ввода движения float moveHorizontal = Input.GetAxis("Horizontal"); float moveVertical = Input.GetAxis("Vertical"); bool isMoving = moveHorizontal != 0 || moveVertical != 0; // Определяем текущую скорость float targetSpeed = walkSpeed; if (Input.GetKey(KeyCode.LeftShift) && !isCrouching) { targetSpeed = runSpeed; } if (isCrouching) { targetSpeed = crouchSpeed; } Vector3 moveDirection = transform.right * moveHorizontal + transform.forward * moveVertical; Vector3 desiredVelocity = moveDirection.normalized * targetSpeed; // Плавное изменение скорости if (isMoving) { currentVelocity = Vector3.MoveTowards(currentVelocity, desiredVelocity, acceleration * Time.deltaTime); } else { currentVelocity = Vector3.MoveTowards(currentVelocity, Vector3.zero, deceleration * Time.deltaTime); } // === Прыжок и гравитация === if (controller.isGrounded) { // Сбрасываем вертикальную скорость, если на земле if (verticalVelocity < 0) { verticalVelocity = -2f; } // Проверяем нажатие клавиши прыжка if (Input.GetButtonDown("Jump") && !isCrouching) { verticalVelocity = Mathf.Sqrt(jumpHeight * -2f * gravity); } } else { // Применяем гравитацию verticalVelocity += gravity * Time.deltaTime; } // Добавляем вертикальную скорость к движению Vector3 move = currentVelocity; move.y = verticalVelocity; float bobOffsetY = 0.9f; float bobOffsetX = 0f; controller.Move(move * Time.deltaTime); // if (controller.isGrounded && !isMoving) //покой // { // bobOffsetY = Mathf.Sin(Time.time * restShakeFrequency) * restShakeIntensity * 0.5f; // bobOffsetX = Mathf.Cos(Time.time * restShakeFrequency * 0.2f) * restShakeIntensity * 0.1f; // playerCamera.transform.localPosition = originalCameraPosition + new Vector3(bobOffsetX, bobOffsetX, 0f); // // Тряска камеры через вращение // float shakeRotationX = Mathf.Sin(Time.time * shakeFrequency * 0.08f) * shakeIntensity; // float shakeRotationY = Mathf.Cos(Time.time * shakeFrequency * 0.2f) * shakeIntensity * 3; // playerCamera.transform.localRotation *= Quaternion.Euler(shakeRotationX, 0f, shakeRotationY); // Применяем тряску через вращение // } // // === Тряска камеры и покачивания === // if (controller.isGrounded && isMoving) // { // bobTimer += Time.deltaTime * 0.1f * targetSpeed; // bobOffsetY = Mathf.Sin(bobTimer * 0.2f) * bobVerticalAmplitude; // bobOffsetX = Mathf.Cos(bobTimer * 0.5f) * Mathf.Cos(Time.time * restShakeFrequency * 0.2f) * restShakeIntensity * 0.1f; ; // playerCamera.transform.localPosition = originalCameraPosition + new Vector3(bobOffsetX, bobOffsetY, 0f); // // Тряска камеры через вращение // float shakeRotationX = Mathf.Sin(Time.time * shakeFrequency * 0.5f) * shakeIntensity * targetSpeed; // float shakeRotationY = Mathf.Cos(Time.time * shakeFrequency) * shakeIntensity * targetSpeed / 3; // playerCamera.transform.localRotation *= Quaternion.Euler(shakeRotationX, 0f, shakeRotationY); // Применяем тряску через вращение // } // else // { // // Сброс тряски, когда игрок не движется // bobTimer = 0.1f; // playerCamera.transform.localPosition = Vector3.Lerp(playerCamera.transform.localPosition, originalCameraPosition, Time.deltaTime * 1f); // } } void Crouch() { controller.height = crouchHeight; isCrouching = true; } void StandUp() { controller.height = standingHeight; isCrouching = false; } }