using UnityEngine; using System.Collections; public class PlayerController : MonoBehaviour { [Header("Movement")] public float speed = 8f; private Rigidbody playerRigidbody; public VirtualJoystick joystick; [Header("Shield System")] public int shieldCount = 3; private bool isShieldActive = false; public GameObject shieldVisual; public ShieldUIHandler shieldUI; [Header("Shooting")] public GameObject bulletPrefab; public Transform firePoint; public int maxAmmo = 6; public float reloadTime = 1.5f; private int currentAmmo; private bool isReloading = false; public ShootButtonUI shootButtonUI; private Vector3 lastMoveDirection = Vector3.forward; void Start() { playerRigidbody = GetComponent(); currentAmmo = maxAmmo; if (shootButtonUI != null) shootButtonUI.UpdateAmmoUI(currentAmmo, maxAmmo); if (shieldUI != null) shieldUI.UpdateShieldUI(shieldCount); } void Update() { HandleMovement(); if (!GameSettings.IsMobile && Input.GetKeyDown(KeyCode.Alpha1)) { ActivateShieldLogic(); } if (!GameSettings.IsMobile && Input.GetKeyDown(KeyCode.Space)) { Shoot(); } } void HandleMovement() { float x = 0, z = 0; if (GameSettings.IsMobile && joystick != null) { Vector2 input = joystick.GetInput(); x = input.x; z = input.y; } else { x = Input.GetAxis("Horizontal"); z = Input.GetAxis("Vertical"); } playerRigidbody.linearVelocity = new Vector3(x * speed, playerRigidbody.linearVelocity.y, z * speed); if (Mathf.Abs(x) > 0.1f || Mathf.Abs(z) > 0.1f) { lastMoveDirection = new Vector3(x, 0, z).normalized; } Animator anim = GetComponentInChildren(); if (anim != null) anim.SetBool("isMoving", (Mathf.Abs(x) > 0.1f || Mathf.Abs(z) > 0.1f)); } public void ActivateShieldLogic() { if (shieldCount > 0 && !isShieldActive) { StartCoroutine(ActivateShieldRoutine()); } } private IEnumerator ActivateShieldRoutine() { isShieldActive = true; shieldCount--; if (shieldUI != null) shieldUI.UpdateShieldUI(shieldCount); if (shieldVisual != null) shieldVisual.SetActive(true); yield return new WaitForSeconds(2f); if (shieldVisual != null) shieldVisual.SetActive(false); isShieldActive = false; } public void Die() { gameObject.SetActive(false); FindFirstObjectByType()?.EndGame(); } public void Shoot(Vector2? inputDirection = null) { // 리로드 중이거나 탄이 없으면 발사 불가 if (isReloading || currentAmmo <= 0) return; if (bulletPrefab == null || firePoint == null) return; // 탄 차감 currentAmmo--; if (shootButtonUI != null) shootButtonUI.UpdateAmmoUI(currentAmmo, maxAmmo); // 방향 결정 Vector3 lookDir; if (inputDirection.HasValue && inputDirection.Value.magnitude > 0.1f) { lookDir = new Vector3(inputDirection.Value.x, 0, inputDirection.Value.y).normalized; lastMoveDirection = lookDir; } else { lookDir = lastMoveDirection; } Quaternion bulletRotation = Quaternion.LookRotation(lookDir); GameObject bullet = Instantiate(bulletPrefab, firePoint.position, bulletRotation); bullet.transform.forward = lookDir; Bullet bulletScript = bullet.GetComponent(); if (bulletScript != null) { bulletScript.isPlayerBullet = true; bulletScript.speed = 8f; } Collider bulletCollider = bullet.GetComponent(); Collider playerCollider = GetComponent(); if (bulletCollider != null && playerCollider != null) { Physics.IgnoreCollision(bulletCollider, playerCollider); } // 마지막 탄을 쐈으면 자동 리로드 시작 if (currentAmmo <= 0) { StartCoroutine(ReloadRoutine()); } } private IEnumerator ReloadRoutine() { isReloading = true; if (shootButtonUI != null) shootButtonUI.SetReloading(true); yield return new WaitForSeconds(reloadTime); currentAmmo = maxAmmo; isReloading = false; if (shootButtonUI != null) { shootButtonUI.SetReloading(false); shootButtonUI.UpdateAmmoUI(currentAmmo, maxAmmo); } } void LateUpdate() { transform.rotation = Quaternion.LookRotation(lastMoveDirection); } }