/
Lexan97
/
Cowbeat
Обзор
Документация
Войти
/
Lexan97
/
Cowbeat
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
Assets/Scripts/Player/PlayerMovement.cs
310 строк
10 KB
Lexa97
Final Commit gor present
26 май 2026, 23:40
26 май 2026, 23:40
70e9bdb
Код
Авторство
О чём код?
using UnityEngine; using System.Collections; public class PlayerMovement : MonoBehaviour { [Header("Base Settings")] [SerializeField] private float rotationSpeed = 720f; [SerializeField] private float jumpSpeed = 5f; [SerializeField] private float jumpHorizontalSpeed = 4f; [SerializeField] private float jumpButtonGracePeriod = 0.2f; [SerializeField] private Transform cameraTransform; [SerializeField] private PlayerCombat playerCombat; [Header("Dodge / Roll Settings")] [SerializeField] private float rollCooldown = 5f; [SerializeField] private float rollColliderHeight = 1f; public KeyCode rollKey = KeyCode.Q; public KeyCode sprintKey = KeyCode.LeftShift; [Header("State Flags")] public bool canMove = true; public bool isRolling = false; private Animator animator; private CharacterController characterController; private AimController aimController; private PlayerStats playerStats; private float ySpeed; private float originalStepOffset; private float? lastGroundedTime; private float? jumpButtonPressedTime; private bool isJumping; private bool isGrounded; private float nextRollTime; private float originalHeight; private Vector3 originalCenter; public bool IsAttacking => playerCombat != null && playerCombat.IsAttacking; void Start() { Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; rollKey = KeyCode.Q; sprintKey = KeyCode.LeftShift; animator = GetComponent<Animator>(); characterController = GetComponent<CharacterController>(); aimController = GetComponent<AimController>(); playerStats = GetComponent<PlayerStats>(); originalStepOffset = characterController.stepOffset; originalHeight = characterController.height; originalCenter = characterController.center; if (playerCombat == null) playerCombat = GetComponent<PlayerCombat>(); } void Update() { if (playerStats.isDead) return; ApplyGravity(); HandleRollInput(); if (isRolling) return; if (!canMove) { animator.SetBool("isMoving", false); animator.SetFloat("Input Magnitude", 0f); return; } if (aimController != null && aimController.isAiming) { jumpButtonPressedTime = null; characterController.Move(new Vector3(0, ySpeed, 0) * Time.deltaTime); animator.SetBool("isMoving", false); animator.SetFloat("Input Magnitude", 0f); HandleJumpAndFall(true); return; } HandleJumpAndFall(false); if (playerCombat != null && playerCombat.IsAttacking) { float timeSinceAttack = Time.time - playerCombat.attackStartTime; if (timeSinceAttack >= playerCombat.JumpCancelDelay && Input.GetButtonDown("Jump")) playerCombat.CancelAttack(); if (timeSinceAttack >= playerCombat.MoveCancelDelay) { float h = Input.GetAxis("Horizontal"); float v = Input.GetAxis("Vertical"); if (Mathf.Abs(h) > 0.1f || Mathf.Abs(v) > 0.1f) { playerCombat.CancelAttack(); HandleFreeMovement(); } } if (playerCombat.IsAttacking) { animator.SetBool("isMoving", false); animator.SetFloat("Input Magnitude", 0f); return; } } HandleFreeMovement(); } private void HandleRollInput() { if (Input.GetKeyDown(rollKey)) { float h = Input.GetAxisRaw("Horizontal"); float v = Input.GetAxisRaw("Vertical"); bool hasMovementInput = Mathf.Abs(h) > 0.01f || Mathf.Abs(v) > 0.01f; if (hasMovementInput && isGrounded && !isRolling && Time.time >= nextRollTime) { if (playerCombat.IsAttacking) { float timeSinceAttack = Time.time - playerCombat.attackStartTime; if (timeSinceAttack < playerCombat.MoveCancelDelay) return; playerCombat.CancelAttack(); } ExecuteRoll(); } } } private void ExecuteRoll() { nextRollTime = Time.time + rollCooldown; animator.SetTrigger("Roll"); } public void AnimationEvent_StartRoll() { isRolling = true; characterController.height = rollColliderHeight; characterController.center = new Vector3(originalCenter.x, rollColliderHeight / 2f, originalCenter.z); characterController.stepOffset = 0.5f; } public void AnimationEvent_EndRoll() { isRolling = false; characterController.height = originalHeight; characterController.center = originalCenter; characterController.stepOffset = originalStepOffset; } private void HandleFreeMovement() { float h = Input.GetAxis("Horizontal"); float v = Input.GetAxis("Vertical"); if (Mathf.Approximately(Time.timeScale, 0f)) return; Vector3 moveDir = new Vector3(h, 0, v); float inputMag = Mathf.Clamp01(moveDir.magnitude); if (moveDir != Vector3.zero) { bool isRunning = Input.GetKey(sprintKey); inputMag = isRunning ? 1.0f : 0.5f; moveDir = Quaternion.AngleAxis(cameraTransform.rotation.eulerAngles.y, Vector3.up) * moveDir; moveDir.Normalize(); Quaternion toRotation = Quaternion.LookRotation(moveDir, Vector3.up); transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, rotationSpeed * Time.deltaTime); animator.SetBool("isMoving", true); } else { animator.SetBool("isMoving", false); } animator.SetFloat("Input Magnitude", inputMag, 0.05f, Time.deltaTime); } private void ApplyGravity() { if (characterController.isGrounded) { lastGroundedTime = Time.time; ySpeed = -2f; } else { ySpeed += Physics.gravity.y * Time.deltaTime; } } private void HandleJumpAndFall(bool lockInput) { if (!lockInput && Input.GetButtonDown("Jump")) jumpButtonPressedTime = Time.time; bool физическиНаЗемле = characterController.isGrounded && ySpeed <= 0f; if (физическиНаЗемле) { isGrounded = true; animator.SetBool("isGrounded", true); isJumping = false; animator.SetBool("isJumping", false); animator.SetBool("isFalling", false); if (jumpButtonPressedTime != null && Time.time - jumpButtonPressedTime <= jumpButtonGracePeriod) { ySpeed = jumpSpeed; isJumping = true; animator.SetBool("isJumping", true); animator.SetBool("isGrounded", false); jumpButtonPressedTime = null; lastGroundedTime = null; } } else if (Time.time - lastGroundedTime <= jumpButtonGracePeriod && !isJumping) { isGrounded = true; animator.SetBool("isGrounded", true); animator.SetBool("isFalling", false); if (jumpButtonPressedTime != null && Time.time - jumpButtonPressedTime <= jumpButtonGracePeriod) { ySpeed = jumpSpeed; isJumping = true; animator.SetBool("isJumping", true); animator.SetBool("isGrounded", false); jumpButtonPressedTime = null; lastGroundedTime = null; } } else { isGrounded = false; animator.SetBool("isGrounded", false); if (ySpeed < -1.0f) { animator.SetBool("isFalling", true); animator.SetBool("isJumping", false); } } } private void OnAnimatorMove() { if (playerStats.isDead) return; if (isRolling) { Vector3 velocity = animator.deltaPosition; velocity.y = ySpeed * Time.deltaTime; characterController.Move(velocity); return; } if (!canMove) { characterController.Move(new Vector3(0, ySpeed, 0) * Time.deltaTime); return; } if (aimController != null && aimController.isAiming) return; Vector3 moveVelocity; if (isGrounded) { if (playerCombat != null && playerCombat.IsAttacking) { moveVelocity = animator.deltaPosition / Time.deltaTime; } else { float speed = animator.deltaPosition.magnitude / Time.deltaTime; float inputMag = animator.GetFloat("Input Magnitude"); if (speed < 0.1f && inputMag > 0.1f) speed = jumpHorizontalSpeed; moveVelocity = transform.forward * speed; } } else { float h = Input.GetAxis("Horizontal"); float v = Input.GetAxis("Vertical"); Vector3 airDir = new Vector3(h, 0, v); airDir = Quaternion.AngleAxis(cameraTransform.rotation.eulerAngles.y, Vector3.up) * airDir; moveVelocity = airDir.normalized * jumpHorizontalSpeed; } moveVelocity.y = ySpeed; characterController.Move(moveVelocity * Time.deltaTime); } }