8298b2559c
1. 게임형태 변경 - Game스텝에서 기존 1단계, 2단계 수정(회전만 가능하게). - ShootButton을 만들어 플레이어도 총알을 쏠수 있도록 수정. - Bullet, BulletSpawner, PlayerController를 수정 - SpawnZone을 생성하여 기존 고정이던 스포너를 랜덤으로 생성. 2. 오류 수정 - 모바일 버전 시 플레이어가 한방향만 보던 형상 수정. - 펜스에서 플레이어 캐릭터가 닿으면 회전하던 형상 수정.
182 lines
4.8 KiB
C#
182 lines
4.8 KiB
C#
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<Rigidbody>();
|
|
|
|
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<Animator>();
|
|
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<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);
|
|
}
|
|
} |