using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; public class Player : MonoBehaviour { private Camera _camera; private Queue _bulletPool = new Queue(); public GameObject bulletPrefab; public int bulletCount = 21; public GameObject backGround; public int moveSpeed = 20; [Header("연사 설정")] public float fireRate = 0.1f; // 총알 발사 간격 (0.1초마다 1발) private float _fireTimer; // 발사 타이머 private bool _isShooting; // 발사 버튼을 누르고 있는지 여부 void Start() { _camera = Camera.main; // 처음 클릭 시 즉시 발사되도록 타이머 초기화 _fireTimer = fireRate; // 기존의 performed 대신 클릭 시작(started)과 종료(canceled) 이벤트를 연결합니다. InputManager.InputSystem.Player.Click.started += OnShootStarted; InputManager.InputSystem.Player.Click.canceled += OnShootCanceled; for (int i = 0; i < bulletCount; i++) { var bullet = Instantiate(bulletPrefab); _bulletPool.Enqueue(bullet); bullet.SetActive(false); } } private void FixedUpdate() { var readValue = InputManager.InputSystem.Player.Move.ReadValue(); var moveDir = new Vector3(readValue.x, readValue.y, 0); transform.position += moveDir * (Time.fixedDeltaTime * moveSpeed); backGround.transform.position = transform.position; } // 마우스를 클릭하기 시작했을 때 private void OnShootStarted(InputAction.CallbackContext obj) { _isShooting = true; } // 마우스 클릭을 뗐을 때 private void OnShootCanceled(InputAction.CallbackContext obj) { _isShooting = false; } // InputAction.CallbackContext 매개변수를 제거하여 Update문에서 호출 가능하게 변경 private void Shoot() { var peek = _bulletPool.Dequeue(); if (peek.activeInHierarchy) { _bulletPool.Enqueue(peek); peek = Instantiate(bulletPrefab, transform); } peek.transform.rotation = transform.rotation; peek.transform.position = transform.position; peek.SetActive(true); _bulletPool.Enqueue(peek); } void Update() { if (_camera is null) { return; } if (InputManager.InputSystem is null) { return; } // 1. 캐릭터 회전 처리 var mousePos = InputManager.InputSystem.Player.Mouse.ReadValue(); var screenToWorldPoint = _camera.ScreenToWorldPoint(mousePos); screenToWorldPoint.z = 0; Vector2 direction = screenToWorldPoint - transform.position; var rad2Deg = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg; transform.rotation = Quaternion.Euler(0, 0, rad2Deg + 90); // 2. 연사 처리 로직 _fireTimer += Time.deltaTime; // 타이머는 매 프레임 증가 if (_isShooting && _fireTimer >= fireRate) { Shoot(); _fireTimer = 0f; // 발사 후 타이머 초기화 } } // 에러나 메모리 누수 방지를 위해 스크립트 파괴 시 이벤트 구독 해제 private void OnDestroy() { if (InputManager.InputSystem != null) { InputManager.InputSystem.Player.Click.started -= OnShootStarted; InputManager.InputSystem.Player.Click.canceled -= OnShootCanceled; } } }