본문 바로가기

Unity/▶ Game Development: Dodge

[Dodge] #5. 탄알 생성기

728x90
반응형

탄알 생성기 생성

Bullet Spawner 게임 오브젝트 생성

  1. 하이어 라키Create > 3D Object > Cylinder
  2. 생성된 오브젝트의 이름을 Bullet Spawner으로 변경
  3. Bullet Spawner 게임 오브젝트의 위치를 (8,1,0)으로 변경
  4. Bullet Spawner에 Bullet Color의 메테리얼을 드레그&드롭

하이어 라키에 탄알 생성기를 만든다.

Bullet Spawner 스크립트 생성

Bullet Spawner의 변수 선언

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletSpawner : MonoBehaviour
{
    public GameObject Bulletprefab;
    public float SpawnRateMin = 0.5f;
    public float SpawnRateMax = 3f;

    private Transform target;
    private float SpawnRate;
    private float timeAfterSpawn;

    void Start(){
    }

    // Update is called once per frame
    void Update()
    {
          
    }
}

변수 설명

public
Bulletprefab
탄알을 생성하는 데 사용할 원본 프리팹
SpawnRateMin
새 탄알을 생성하는 데 걸리는 시간의 최솟값
SpawnRateMax
 탄알을 생성하는 데 걸리는 시간의 최댓값
private
target
조준할 대상 게임 오브젝트의 트랜스폼 컴포넌트
SpawnRate
다음 탄알을 생성할 때까지 기다릴 시간
timeAfterSpawn
마지막 탄알 생성 시점부터 흐른 시간을 표시하는 타이머

Start() 메서드

void Start(){
    timeAfterSpawn = 0f;
    SpawnRate = Random.Range(SpawnRateMin,SpawnRateMax);
    target = FindObjectOfType<PlayerController>().transform;
}
  • 흐른 시간 타이머(timeAfterSpawn) 초기화
  • 다음 탄알 생성할 때까지 기다릴 시간(SpawnRate)의 값을 랜점으로 설정. 이때 범위는 SpawnRateMin~SpawnRateMax
  • 조준할 대상인 target을 FindObjectOfType메서드를 이용해 할당

Random.Range() 메서드

  • Random.Range()는 인자로 들어오는 값에 따라 동작이 다르다.
정수(int x,int y) 정수 x,y 사이의 값이 랜덤으로 정수 형태로 발생
실수(float x,float y) 정수 x,y 사이의 값이 랜덤으로 실수 형태로 발생

FindObjectOfType() 메서드

target에 Player 게임 오브젝트 트랜스폼을 할당하는 방법에는 target필드에 Player 게임 오브젝트를 직접 드래그&드롭하는 방법이 있지만 많은 탄알 생성기가 있을 때 번거로우므로, 코드 상에서 Player 게임 오브젝트의 트랜스폼 컴포넌트를 찾아서 가져오는 방식을 취한다.

 

FindObjectOfType() 메서드는 꺽쇠<>안에 어떤 타입을 명시하면 씬에 있는 모든 오브젝트를 검색하여 해당 타입의 오브젝틀 가져온다.

 

target = FindObjectOfType<PlayerController>().transform;

FindObjectOfType 메서드를 사용하여 PlayerController 컴포넌트를 찾아 해당 컴포넌트의 트랜스폼 컴포넌트(위치)를 target에 할당하였다.

 

이때 FindObjectOfType 메서드는 씬에 있는 모든 컴포넌트를 검색하므로 처리 비용이 크다. 따라서 게임을 실행할 때 한 번만 실행하는 Start메서드에 사용하는 것이 바람직하다.

일정 주기로 실행 반복하기

탄알을 계속 생성하면 1초에 수십개씩 생성되므로, 이러한 문제점을 방지하기 위해 탄알을 생성하기 전에 마지막으로 탄알을 생성한 시점에서 누적된 시간을 저장하는 timeAfterSpawn를 체크하여 탄알의 생성을 억제해야한다.

Update() 메서드

void Update()
{
    timeAfterSpawn += Time.deltaTime;
    if(timeAfterSpawn>= SpawnRate){
        timeAfterSpawn = 0f;

        GameObject bullet = Instantiate(Bulletprefab,transform.position,transform.rotation);
        bullet.transform.LookAt(target);

        SpawnRate = Random.Range(SpawnRateMin,SpawnRateMax);
    }   
}

Time.deltaTime 메서드

  • Update() 실행 사이의 시간 간격을 알기 위해 내장 변수 Time.deltaTime 를 사용한다. 
  • Time.deltaTime에는 이전 프레임과 현재 프레임 사이의 시간 간격이 자동으로 할당된다.

어떤 변수에 Time.deltaTime를 누적하면 특정 시점으로 부터의 시간이 얼마나 흘렀는지 알 수 있다.

timeAfterSpawn += Time.deltaTime;

Instantiate() 메서드

Instantiate(Prefab);

Instantiate() 메서드는 원본 오브젝트를 주면 해당 오브젝트를 복제한 오브젝트를 생성한다.

Instantiate(원본)

 

인자가 오브젝트만 가질 때에는 복제 생성된 게임 오브젝트의 위치와 회전이 임의로 설정된다.

Instantiate(원본,위치,회전)

 

 

인자로 원본의 변수의 이름과 위치, 회전을 넣어 초기화 할 수 있다.

Instantiate(Bulletprefab,transform.position,transform.rotation);
transform.position
자신의 위치
transform.rotation 자신의 회전

LookAt() 메서드

bullet.transform.LookAt(target);

 

LookAt 메서드를 사용하여 복제 생성된 bullet 이라는 변수가 target을 보도록 설정한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletSpawner : MonoBehaviour
{
    public GameObject Bulletprefab;
    public float SpawnRateMin = 0.5f;
    public float SpawnRateMax = 3f;

    private Transform target;
    private float SpawnRate;
    private float timeAfterSpawn;
    // Start is called before the first frame update
    void Start(){
        
        timeAfterSpawn = 0f;
        SpawnRate = Random.Range(SpawnRateMin,SpawnRateMax);
        target = FindObjectOfType<PlayerController>().transform;
    }

    // Update is called once per frame
    void Update()
    {
        timeAfterSpawn += Time.deltaTime;
        if(timeAfterSpawn>= SpawnRate){
            timeAfterSpawn = 0f;

            GameObject bullet = Instantiate(Bulletprefab,transform.position,transform.rotation);
            bullet.transform.LookAt(target);

            SpawnRate = Random.Range(SpawnRateMin,SpawnRateMax);
        }   
    }
}

 탄알 생성기 배치하기

탄알 생성기 4개 배치

다음과 같이 탄알 생성기를 배치하여 완료한다.

 

완료코드

bullet

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour {
    public float speed = 8f; // 총알 이동 속력
    private Rigidbody bulletRigidbody; // 이동에 사용할 리지드바디 컴포넌트

    void Start() {
        // 게임 오브젝트에서 Rigidbody 컴포넌트를 찾아 bulletRigidbody에 할당
        bulletRigidbody = GetComponent<Rigidbody>();
        // 리지드바디의 속도 = 앞쪽 방향 * 이동 속력
        bulletRigidbody.velocity = transform.forward * speed;

        // 3초 뒤에 자신의 게임 오브젝트 파괴
        Destroy(gameObject, 3f);
    }

    // 트리거 충돌 시 자동으로 실행되는 메서드

    void OnTriggerEnter(Collider property){
        if(property.tag == "Player"){
            Debug.Log("Player Collision!");
            PlayerController playerController = property.GetComponent<PlayerController>();

            // 상대방으로부터 PlayerController 컴포넌트를 가져오는데 성공했다면
            if (playerController != null) {
                Debug.Log("playerController is not null");
                playerController.Die();
                Application.Quit();
            }
            else{
                Debug.Log("playerController is null");
            }
            
        }

        if(property.tag== "bullet"){
            Debug.Log("bullet to bullet OnTriggerEnter Collision!");
            Destroy(gameObject);
        }
    }

    // void OnCollisionEnter(Collision collision)
	// {
    //     if(collision.transform.tag == "Player") Destroy(gameObject);
    //     if(collision.transform.tag== "bullet"){
    //         Debug.Log("bullet to bullet Collision!");
    //         Destroy(gameObject);
    //     }
        
	// }
    
}

!!!주의점!!!

OnTriggerEnter메소드는 트리거 영역으로 인해 발생한다. 즉, 트리거 영역이 서로 접접이 없으면 발생하지 않는다는 이야기! 따라서 해당 메소드가 발생하지 않으면 Edit Colider을 통해 트리거의 영역을 확인하도록하자!
728x90
반응형

'Unity > ▶ Game Development: Dodge' 카테고리의 다른 글

[Dodge] #7. 게임 완성  (1) 2022.03.02
[Dodge] #6. 바닥 회전  (0) 2022.03.02
[Dodge] #4. 탄알 생성  (0) 2022.02.25
[Dodge] #3. 스크립트 개선하기  (0) 2022.02.24
[Dodge] #2. 플레이어  (0) 2022.02.04
댓글