Files
PGiZ4/Assets/Code/Gameplay/Player/PlayerController.cs
T
2026-03-07 23:43:08 +03:00

115 lines
3.3 KiB
C#

using UnityEngine;
namespace Code.Gameplay.Player
{
public class PlayerController : MonoBehaviour
{
[SerializeField] private float forwardSpeed = 10f;
[SerializeField] private float maxSpeed = 40f;
[SerializeField] private float laneDistance = 5f;
[SerializeField] private float jumpForce = 11f;
[SerializeField] private float gravity = 20f;
private int _targetLane = 1;
private CharacterController _controller;
private Vector3 _direction;
public System.Action OnPlayerDeath;
private bool _isDead = false;
private void Start()
{
_controller = GetComponent<CharacterController>();
}
private void Update()
{
if (_isDead) return;
if (UnityEngine.Input.GetKeyDown(KeyCode.RightArrow) || UnityEngine.Input.GetKeyDown(KeyCode.D))
{
_targetLane = Mathf.Min(_targetLane + 1, 2);
}
else if (UnityEngine.Input.GetKeyDown(KeyCode.LeftArrow) || UnityEngine.Input.GetKeyDown(KeyCode.A))
{
_targetLane = Mathf.Max(_targetLane - 1, 0);
}
var targetPosition = transform.position.z * transform.forward + transform.position.y * transform.up;
switch (_targetLane)
{
case 0:
targetPosition += Vector3.left * laneDistance;
break;
case 2:
targetPosition += Vector3.right * laneDistance;
break;
}
if (_controller.isGrounded)
{
_direction.y = -1f;
if (UnityEngine.Input.GetKeyDown(KeyCode.Space))
{
_direction.y = jumpForce;
}
}
else
{
_direction.y -= gravity * Time.deltaTime;
}
_direction.z = forwardSpeed;
var diff = targetPosition - transform.position;
var moveDir = diff.normalized * (25f * Time.deltaTime);
var moveX = Mathf.Clamp(diff.x, -moveDir.magnitude, moveDir.magnitude);
var finalMove = new Vector3(moveX, _direction.y * Time.deltaTime, _direction.z * Time.deltaTime);
_controller.Move(finalMove);
CheckForDeath();
}
public void IncreaseSpeed(float amount)
{
if (forwardSpeed < maxSpeed)
{
var desirableSpeed = forwardSpeed + amount;
forwardSpeed = Mathf.Min(desirableSpeed, maxSpeed);
}
}
private void OnTriggerEnter(Collider foreign)
{
if (foreign.CompareTag("Coin"))
{
UI.GameplayController.Instance.AddCoin();
Destroy(foreign.gameObject);
}
}
private void CheckForDeath()
{
if (_isDead) return;
if (Time.timeSinceLevelLoad > 1f && _controller.velocity.z <= 0.1f)
{
Die();
}
}
private void Die()
{
_isDead = true;
forwardSpeed = 0;
_direction = Vector3.zero;
OnPlayerDeath?.Invoke();
}
}
}