pgiz4_moi/Assets/Scripts/PlayerController.cs
2026-03-24 20:20:32 +03:00

139 lines
3.9 KiB
C#

using UnityEngine;
using System;
[RequireComponent(typeof(Animator), typeof(CapsuleCollider))]
public class PlayerController : MonoBehaviour
{
[Header("Movement")]
public float moveSpeed = 8f;
public float speedIncreaseRate = 0.1f;
public float jumpForce = 10f;
public float laneChangeSpeed = 15f;
public float laneWidth = 4f;
[Header("Collider")]
public float slideColliderHeight = 0.5f;
public float slideColliderCenterY = 0.25f;
private Rigidbody rb;
private Animator animator;
private CapsuleCollider capsuleCollider;
private bool isGrounded = true;
private bool isSliding = false;
private int currentLane = 0;
private Vector3 targetPosition;
private float originalColliderHeight;
private float originalColliderCenterY;
public static int coinCount = 0;
public static event Action OnPlayerDied;
private bool isAlive = true;
void Start()
{
rb = GetComponent<Rigidbody>();
animator = GetComponent<Animator>();
capsuleCollider = GetComponent<CapsuleCollider>();
originalColliderHeight = capsuleCollider.height;
originalColliderCenterY = capsuleCollider.center.y;
coinCount = 0;
isAlive = true;
Time.timeScale = 1f;
targetPosition = transform.position;
}
void Update()
{
if (!isAlive) return;
moveSpeed += speedIncreaseRate * Time.deltaTime;
HandleInput();
MovePlayer();
}
void HandleInput()
{
if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) ChangeLane(-1);
else if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow)) ChangeLane(1);
if (Input.GetKeyDown(KeyCode.Space) && isGrounded) Jump();
if (Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) Slide();
}
void MovePlayer()
{
targetPosition.x = currentLane * laneWidth;
Vector3 newPosition = new Vector3(
Mathf.Lerp(transform.position.x, targetPosition.x, laneChangeSpeed * Time.deltaTime),
transform.position.y,
transform.position.z + moveSpeed * Time.deltaTime
);
transform.position = newPosition;
}
void ChangeLane(int direction)
{
int newLane = currentLane + direction;
if (newLane >= -1 && newLane <= 1) currentLane = newLane;
}
void Jump()
{
isGrounded = false;
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
animator.SetTrigger("Jump");
}
void Slide()
{
if (!isSliding)
{
isSliding = true;
animator.SetTrigger("Slide");
capsuleCollider.height = slideColliderHeight;
capsuleCollider.center = new Vector3(0, slideColliderCenterY, 0);
Invoke(nameof(StopSliding), 0.75f);
}
}
void StopSliding()
{
isSliding = false;
capsuleCollider.height = originalColliderHeight;
capsuleCollider.center = new Vector3(0, originalColliderCenterY, 0);
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Ground")) isGrounded = true;
else if (collision.gameObject.CompareTag("Obstacle") && isAlive) Die();
else if (collision.gameObject.CompareTag("HighObstacle") && !isSliding && isAlive) Die();
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Coin") && isAlive)
{
coinCount++;
// Вызываем AudioManager для проигрывания звука
AudioManager.Instance.PlayCoinSound();
Destroy(other.gameObject);
}
}
void Die()
{
isAlive = false;
animator.SetBool("IsDead", true);
if (OnPlayerDied != null) Invoke(nameof(TriggerGameOver), 1.5f);
}
void TriggerGameOver()
{
Time.timeScale = 0f;
OnPlayerDied();
}
}