적에게 총기 달기
일단 먼저 애니메이션만 존재하는 적 오브젝트에게 총기를 달아 주었습니다.
적의 손 부분의 하위로 총을 넣어서 같이 움직이도록 해 주었습니다.
Gun 스크립트
기본적으로 플레이어가 사용하고 있는 스크립트에서 적이 총을 쏘는데 필요없는 부분을 빼고
오브젝트 풀링으로 총알을 재사용 하는 부분과 총알을 발사하는 부분, 총알의 정확도와 방향을 계산하는 부분을 가져와 따로 EnemyGun 스크립트를 만들었습니다.
오브젝트 풀
private List<GameObject> bulletPool; private int poolSize; private void Awake() { // 오브젝트 풀 초기화 InitializeBulletPool(); // 초기 정확도 설정 currentAccuracy = gunData.baseAccuracy; } private void InitializeBulletPool() { // 오브젝트 풀 생성 bulletPool = new List<GameObject>(); poolSize = (gunData.gunType == GunType.SHOTGUN) ? gunData.magazineSize * gunData.shotgunPellets : gunData.magazineSize; for (int i = 0; i < poolSize; i++) { // 오브젝트 생성 및 비활성화 GameObject obj = Instantiate(bulletPrefab); obj.SetActive(false); bulletPool.Add(obj); } }
오브젝트 풀을 크기에 맞게 생성하고 비활성화 시킵니다.
샷건과 일반 총 구분
public void Shoot() { if (gunData.gunType == GunType.SHOTGUN) { for (int i = 0; i < gunData.shotgunPellets; i++) { GameObject bulletObject = GetPooledBullet(); if (bulletObject != null) { FireBullet(bulletObject); } } } else { GameObject bulletObject = GetPooledBullet(); if (bulletObject != null) { FireBullet(bulletObject); } } } private GameObject GetPooledBullet() { for (int i = 0; i < bulletPool.Count; i++) { if (!bulletPool[i].activeInHierarchy) { return bulletPool[i]; } } // 사용 가능한 총알이 없으면 새로운 총알 생성 GameObject obj = Instantiate(bulletPrefab); obj.SetActive(false); bulletPool.Add(obj); return obj; }
샷건과 다른 총을 구분하여 총알이 발사되는 개수를 조절합니다. 총알은 오브젝트 풀을 이용하여 생성합니다.
총알 발사와 방향, 정확도 계산
private void FireBullet(GameObject bulletObject) { bulletObject.SetActive(true); Rigidbody rb = bulletObject.GetComponent<Rigidbody>(); Bullet bulletComponent = bulletObject.GetComponent<Bullet>(); if (bulletComponent != null) { bulletComponent.damage = gunData.damage; } rb.transform.position = bulletSpawn.position; rb.transform.rotation = bulletSpawn.rotation; Vector3 inaccuracy = Random.insideUnitSphere * (1f - currentAccuracy) * 0.05f; Vector3 direction = (transform.forward + new Vector3(inaccuracy.x, inaccuracy.y, 0f)).normalized; rb.velocity = direction * gunData.bulletSpeed; }
총의 정확도를 gundata의 baseAccuracy에서 가져와 계산을 한 후 방향에 더해준 뒤 bulletSpeed를 곱하여 총알을 발사합니다.
공격 상태에 총알을 발사하는 shoot 넣기
if (Time.time - lastShootTime >= weapon.gunData.fireInterval) { weapon.Shoot(); lastShootTime = Time.time; }
Enemy의 AttackState에 Update 부분에 gundata에 있는 발사 간격 값을 가져와 총알이 빠르게 발사되는것을 막습니다.
이렇게 총알이 한발 씩 나가게 됩니다.