탄알 생성기 생성
Bullet Spawner 게임 오브젝트 생성
- 하이어 라키 > Create > 3D Object > Cylinder
- 생성된 오브젝트의 이름을 Bullet Spawner으로 변경
- Bullet Spawner 게임 오브젝트의 위치를 (8,1,0)으로 변경
- 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);
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);
}
}
}
탄알 생성기 배치하기
다음과 같이 탄알 생성기를 배치하여 완료한다.
완료코드
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);
// }
// }
}
!!!주의점!!!
'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 |