Загрузка данных


using System.Collections;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [Header("Movement")]
    public float moveSpeed = 5f;
    public Rigidbody2D rb;
    public Animator animator;
    public SpriteRenderer spriteRenderer;

    [Header("Dash")]
    public float dashSpeed = 15f;
    public float dashDuration = 0.2f;
    public float dashCooldown = 1f;
    private bool isDashing;
    private bool canDash = true;

    [Header("Combat")]
    public Transform attackPoint;      // Точка, где происходит взрыв/удар
    public float attackRange = 0.5f;   // Радиус поражения
    public float attackRate = 2f;      // Ударов в секунду
    public int attackDamage = 20;      // Урон
    public LayerMask enemyLayers;      // Слой врагов
    private float nextAttackTime = 0f;

    private Vector2 moveInput;
    private Vector2 lastMoveDirection = Vector2.right; // Для атаки в простое

    void Update()
    {
        if (isDashing) return;

        moveInput.x = Input.GetAxisRaw("Horizontal");
        moveInput.y = Input.GetAxisRaw("Vertical");

        // Запоминаем последнее направление для атаки
        if (moveInput != Vector2.zero)
        {
            lastMoveDirection = moveInput.normalized;
        }

        // Логика поворота и смещение точки атаки
        FlipAndMoveAttackPoint();

        // Анимации
        if (moveInput != Vector2.zero)
        {
            animator.SetFloat("Horizontal", moveInput.x);
            animator.SetFloat("Vertical", moveInput.y);
        }
        animator.SetFloat("Speed", moveInput.sqrMagnitude);

        // Ввод атаки
        if (Time.time >= nextAttackTime)
        {
            if (Input.GetKeyDown(KeyCode.Space)) // Атака на Пробел
            {
                Attack();
                nextAttackTime = Time.time + 1f / attackRate;
            }
        }

        // Рывок
        if (Input.GetKeyDown(KeyCode.LeftShift) && canDash && moveInput != Vector2.zero)
            StartCoroutine(Dash());
    }

    void FlipAndMoveAttackPoint()
    {
        if (moveInput.x > 0.1f)
        {
            spriteRenderer.flipX = false;
            // Смещаем точку атаки вправо относительно игрока
            attackPoint.localPosition = new Vector2(0.5f, 0); 
        }
        else if (moveInput.x < -0.1f)
        {
            spriteRenderer.flipX = true;
            // Смещаем точку атаки влево
            attackPoint.localPosition = new Vector2(-0.5f, 0);
        }
        
        // Дополнительно: смещение вверх/вниз для более точной боевки
        if (moveInput.y > 0.1f) attackPoint.localPosition = new Vector2(0, 0.5f);
        else if (moveInput.y < -0.1f) attackPoint.localPosition = new Vector2(0, -0.5f);
    }

    void Attack()
    {
        // Запуск анимации (создайте триггер "Attack" в Animator)
        animator.SetTrigger("Attack");

        // Обнаруживаем врагов в радиусе
        Collider2D[] hitEnemies = Physics2D.OverlapCircleAll(attackPoint.position, attackRange, enemyLayers);

        // Наносим урон каждому
        foreach (Collider2D enemy in hitEnemies)
        {
            Debug.Log("Попали по " + enemy.name);
            // Предполагается, что у врага есть скрипт Enemy с методом TakeDamage
            // enemy.GetComponent<Enemy>().TakeDamage(attackDamage);
        }
    }

    void FixedUpdate()
    {
        if (isDashing) return;
        rb.MovePosition(rb.position + moveInput.normalized * moveSpeed * Time.fixedDeltaTime);
    }

    private IEnumerator Dash()
    {
        canDash = false;
        isDashing = true;
        rb.linearVelocity = moveInput.normalized * dashSpeed;
        yield return new WaitForSeconds(dashDuration);
        isDashing = false;
        rb.linearVelocity = Vector2.zero;
        yield return new WaitForSeconds(dashCooldown);
        canDash = true;
    }

    // Отрисовка сферы атаки в редакторе для удобства
    void OnDrawGizmosSelected()
    {
        if (attackPoint == null) return;
        Gizmos.DrawWireSphere(attackPoint.position, attackRange);
    }
}