Загрузка данных
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);
}
}