Files
PGiZ4/Assets/Code/Gameplay/Player/PlayerController.cs
T

151 lines
4.2 KiB
C#

using System;
using Code.UI;
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 Action OnPlayerDeath;
private bool _isDead;
private bool _isDoubleCoins;
private float _bonusTimer;
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();
HandleBonusTimer();
}
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("Obstacle"))
{
Die();
}
if (foreign.CompareTag("Coin"))
{
var amount = _isDoubleCoins ? 2 : 1;
for(var i = 0; i < amount; i++) GameplayController.Instance.AddCoin();
Destroy(foreign.gameObject);
}
if (foreign.CompareTag("BonusX2"))
{
ActivateDoubleCoins(10f);
Destroy(foreign.gameObject);
}
}
private void ActivateDoubleCoins(float duration)
{
_isDoubleCoins = true;
_bonusTimer = duration;
}
private void HandleBonusTimer()
{
if (_bonusTimer > 0)
{
_bonusTimer -= Time.deltaTime;
if (_bonusTimer <= 0)
{
_isDoubleCoins = false;
}
}
}
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();
}
}
}