TIL (70) | 2023.11.03 |유니티 총 발사

kjg5370·2023년 11월 3일
0

TIL

목록 보기
69/91
post-thumbnail

들어가기 앞서

오늘은 enemy의 무기를 구현해 보았습니다. 플레이어가 총을 사용하는데 필요한 스크립트를 참고하여 enemy가 총을 발사하는데 필요한 것들만 넣어서 따로 enemygun 스크립트를 만들어 보았습니다.

오늘 배운 것

  • 적에게 총기 달기
    일단 먼저 애니메이션만 존재하는 적 오브젝트에게 총기를 달아 주었습니다.

    적의 손 부분의 하위로 총을 넣어서 같이 움직이도록 해 주었습니다.

  • 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에 있는 발사 간격 값을 가져와 총알이 빠르게 발사되는것을 막습니다.

    이렇게 총알이 한발 씩 나가게 됩니다.

진행 사항

  • 적 타입 만들기
    • 기본 적(소총)
      • 기본 애니메이션 처리
        • 애니메이션 종류
          • 대기
          • 걷기
          • 뛰기
          • 사격
    • 근거리 적
      • 근거리 적 만의 애니메이션 처리
        • 근접 공격
        • 콤보 어택
    • 원거리 적
      • 원거리 적 만의 애니메이션 처리
        • 앉기
        • 앉아서 쏘기
  • 레이를 이용하여 플레이어 추적
    • 공격 범위 내에 enemy가 바라보는 방향으로 레이를 쏴서 플레이어면 공격하도록 변경
  • 적 기본 동작 추가
    • RandomWalkState 추가
  • 적의 무기 추가
    • 원거리 무기
      gundata의 fireInterval에 의해 연사 속도 조절
      • 반자동 소총
      • 저격 소총
    • 근접 무기
      적이 공격하는 애니메이션이 진행되는 동안만 콜라이더 활성화
profile
학생입니다

0개의 댓글