[Update] 게임형식 및 오류수정

1. 게임형태 변경
  - Game스텝에서 기존 1단계, 2단계 수정(회전만 가능하게).
  - ShootButton을 만들어 플레이어도 총알을 쏠수 있도록 수정.
  - Bullet, BulletSpawner, PlayerController를 수정
  - SpawnZone을 생성하여 기존 고정이던 스포너를 랜덤으로 생성.

2. 오류 수정
 - 모바일 버전 시 플레이어가 한방향만 보던 형상 수정.
 - 펜스에서 플레이어 캐릭터가 닿으면 회전하던 형상 수정.
This commit is contained in:
jongjae0305
2026-04-29 09:22:08 +09:00
parent ed1e24be1d
commit 8298b2559c
34 changed files with 3558 additions and 2408 deletions
+101 -10
View File
@@ -12,13 +12,28 @@ public class PlayerController : MonoBehaviour
public int shieldCount = 3;
private bool isShieldActive = false;
public GameObject shieldVisual;
public ShieldUIHandler shieldUI; // UI 전용 스크립트 참조
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<Rigidbody>();
// 초기 UI 상태 반영
currentAmmo = maxAmmo;
if (shootButtonUI != null) shootButtonUI.UpdateAmmoUI(currentAmmo, maxAmmo);
if (shieldUI != null) shieldUI.UpdateShieldUI(shieldCount);
}
@@ -26,11 +41,15 @@ public class PlayerController : MonoBehaviour
{
HandleMovement();
// PC 입력 처리 (모바일 아닐 때만)
if (!GameSettings.IsMobile && Input.GetKeyDown(KeyCode.Alpha1))
{
ActivateShieldLogic();
}
if (!GameSettings.IsMobile && Input.GetKeyDown(KeyCode.Space))
{
Shoot();
}
}
void HandleMovement()
@@ -40,7 +59,8 @@ public class PlayerController : MonoBehaviour
if (GameSettings.IsMobile && joystick != null)
{
Vector2 input = joystick.GetInput();
x = input.x; z = input.y;
x = input.x;
z = input.y;
}
else
{
@@ -48,16 +68,16 @@ public class PlayerController : MonoBehaviour
z = Input.GetAxis("Vertical");
}
playerRigidbody.linearVelocity = new Vector3(x * speed, 0f, z * speed);
playerRigidbody.linearVelocity = new Vector3(x * speed, playerRigidbody.linearVelocity.y, z * speed);
if (x != 0 || z != 0)
if (Mathf.Abs(x) > 0.1f || Mathf.Abs(z) > 0.1f)
{
transform.rotation = Quaternion.LookRotation(new Vector3(x, 0f, z));
lastMoveDirection = new Vector3(x, 0, z).normalized;
}
// 애니메이션
Animator anim = GetComponentInChildren<Animator>();
if (anim != null) anim.SetBool("isMoving", (x != 0 || z != 0));
if (anim != null) anim.SetBool("isMoving", (Mathf.Abs(x) > 0.1f || Mathf.Abs(z) > 0.1f));
}
public void ActivateShieldLogic()
@@ -73,7 +93,6 @@ public class PlayerController : MonoBehaviour
isShieldActive = true;
shieldCount--;
// UI 업데이트 위임
if (shieldUI != null) shieldUI.UpdateShieldUI(shieldCount);
if (shieldVisual != null) shieldVisual.SetActive(true);
@@ -88,4 +107,76 @@ public class PlayerController : MonoBehaviour
gameObject.SetActive(false);
FindFirstObjectByType<GameManager>()?.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<Bullet>();
if (bulletScript != null)
{
bulletScript.isPlayerBullet = true;
bulletScript.speed = 8f;
}
Collider bulletCollider = bullet.GetComponent<Collider>();
Collider playerCollider = GetComponent<Collider>();
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);
}
}