139 lines
3.9 KiB
C#
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();
|
|
}
|
|
}
|