2026-04-17 02:00:40 +09:00
|
|
|
using System;
|
2026-04-16 21:14:05 +09:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.InputSystem;
|
|
|
|
|
|
|
|
|
|
public class Player : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
private Camera _camera;
|
|
|
|
|
private Queue<GameObject> _bulletPool = new Queue<GameObject>();
|
|
|
|
|
|
|
|
|
|
public GameObject bulletPrefab;
|
2026-04-17 02:00:40 +09:00
|
|
|
public int bulletCount = 21;
|
|
|
|
|
public GameObject backGround;
|
|
|
|
|
public int moveSpeed = 20;
|
2026-04-16 21:14:05 +09:00
|
|
|
|
|
|
|
|
[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) 이벤트를 연결합니다.
|
2026-04-17 02:00:40 +09:00
|
|
|
InputManager.InputSystem.Player.Click.started += OnShootStarted;
|
|
|
|
|
InputManager.InputSystem.Player.Click.canceled += OnShootCanceled;
|
2026-04-16 21:14:05 +09:00
|
|
|
|
|
|
|
|
for (int i = 0; i < bulletCount; i++)
|
|
|
|
|
{
|
|
|
|
|
var bullet = Instantiate(bulletPrefab);
|
|
|
|
|
_bulletPool.Enqueue(bullet);
|
|
|
|
|
bullet.SetActive(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-17 02:00:40 +09:00
|
|
|
private void FixedUpdate()
|
|
|
|
|
{
|
|
|
|
|
var readValue = InputManager.InputSystem.Player.Move.ReadValue<Vector2>();
|
|
|
|
|
var moveDir = new Vector3(readValue.x, readValue.y, 0);
|
|
|
|
|
transform.position += moveDir * (Time.fixedDeltaTime * moveSpeed);
|
|
|
|
|
backGround.transform.position = transform.position;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-16 21:14:05 +09:00
|
|
|
// 마우스를 클릭하기 시작했을 때
|
|
|
|
|
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<Vector2>();
|
|
|
|
|
var screenToWorldPoint = _camera.ScreenToWorldPoint(mousePos);
|
|
|
|
|
screenToWorldPoint.z = 0;
|
|
|
|
|
|
|
|
|
|
Vector2 direction = screenToWorldPoint - transform.position;
|
|
|
|
|
var rad2Deg = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
|
2026-04-17 02:00:40 +09:00
|
|
|
transform.rotation = Quaternion.Euler(0, 0, rad2Deg + 90);
|
2026-04-16 21:14:05 +09:00
|
|
|
|
|
|
|
|
// 2. 연사 처리 로직
|
|
|
|
|
_fireTimer += Time.deltaTime; // 타이머는 매 프레임 증가
|
|
|
|
|
|
|
|
|
|
if (_isShooting && _fireTimer >= fireRate)
|
|
|
|
|
{
|
|
|
|
|
Shoot();
|
|
|
|
|
_fireTimer = 0f; // 발사 후 타이머 초기화
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 에러나 메모리 누수 방지를 위해 스크립트 파괴 시 이벤트 구독 해제
|
|
|
|
|
private void OnDestroy()
|
|
|
|
|
{
|
|
|
|
|
if (InputManager.InputSystem != null)
|
|
|
|
|
{
|
2026-04-17 02:00:40 +09:00
|
|
|
InputManager.InputSystem.Player.Click.started -= OnShootStarted;
|
|
|
|
|
InputManager.InputSystem.Player.Click.canceled -= OnShootCanceled;
|
2026-04-16 21:14:05 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|