먼저 적 전투기 생성 위치를 더 추가해보도록 하겠습니다.
좌우 각 2개씩 4개가 추가되어 스폰포인트는 총 9개가 되었습니다. GameManager 스크립트에 있는 배열을 갱신해줍니다.
이어서, GameManager 스크립트에서 스폰 포인트 선택 난수 로직을 수정합니다.
난수 0~4 사이 출력 -> 0~8 사이 출력으로 수정
void spawnEnemy() {
int ranPoint = Random.Range(0, 9);
}
그 다음으로 양 옆에서 나오는 전투기들의 방향을 수정해 보겠습니다.
void spawnEnemy() {
//Enemy Spawn
int ranEnemy = Random.Range(0, 3);
int ranPoint = Random.Range(0, 9);
GameObject enemy = Instantiate(enemyObjs[ranEnemy], spawnPoint[ranPoint].position, spawnPoint[ranPoint].rotation);
Enemy enemyScript = enemy.GetComponent<Enemy>();
Rigidbody2D rigid = enemy.GetComponent<Rigidbody2D>();
if (ranPoint == 5 || ranPoint == 7)//왼쪽에서 스폰
{
enemy.transform.Rotate(new Vector3(0, 0, 45)); //45도 회전
rigid.velocity = new Vector2(enemyScript.speed, -1); //남동쪽으로 이동
}
else if (ranPoint == 6 || ranPoint == 8)//오른쪽에서 스폰
{
enemy.transform.Rotate(new Vector3(0, 0, -45)); //45도 회전
rigid.velocity = new Vector2(enemyScript.speed * -1, -1); //남서쪽으로 이동
}
else { //탑에서 스폰
rigid.velocity = Vector2.down * enemyScript.speed;
}
}
이제 적 전투기가 총알을 쏘도록 구현해보겠습니다.
먼저, 플레이어 Bullet 프리펩을 복사 수정해 적 전투기용 Bullet 프리펩을 만들겠습니다.
총알 프리펩 하나를 Ctrl + D를 눌러 복사
잘 보면 복사한 프리펩의 인스펙터에서는 이름 수정이 되지 않는 걸 볼 수 있습니다. 따라서 Open Prefab 클릭
프리펩 창이 뜨는데, 인스펙터에서 이름을 수정하고, 스프라이트를 바꿔줍니다.
프리펩 창은 자동저장이 되므로 프리펩 창을 나가더라도 변경사항이 적용됩니다.
위처럼 Enemy Bullet A 타입과 B타입을 만들어줍니다.
그리고 아래 변수를 추가하고, 적 전투기 각각에 Enemy Bullet 2종을 맵핑해줍니다.
public float maxShotDelay;
public float curShotDelay;
public string enemyName;
//Bullets & Player
public GameObject bulletObjA;
public GameObject bulletObjB;
위 사진 속 Enemy Name이 S와 L인 적 전투기만 총알을 쏘게 구현하겠습니다.
void Update(){
fire();
reload();
}
void fire()
{
if (curShotDelay < maxShotDelay)
{
return;
}
if (enemyName == "S")
{
GameObject bullet = Instantiate(bulletObjA, transform.position + new Vector3(0, -0.7f, 0), transform.rotation);
Rigidbody2D rigid = bullet.GetComponent<Rigidbody2D>();
Vector3 dirVec = player.transform.position - transform.position; //플레이어 위치 - 적 전투기 위치
rigid.AddForce(dirVec.normalized * 5, ForceMode2D.Impulse); //normalized로 dirVec을 단위 값(1)로 변환
}
else if (enemyName == "L") {
GameObject bulletL = Instantiate(bulletObjB, transform.position + new Vector3(-0.2f, -0.7f, 0), transform.rotation);
GameObject bulletR = Instantiate(bulletObjB, transform.position + new Vector3(0.2f, -0.7f, 0), transform.rotation);
Rigidbody2D rigidL = bulletL.GetComponent<Rigidbody2D>();
Rigidbody2D rigidR = bulletR.GetComponent<Rigidbody2D>();
Vector3 dirVecL = player.transform.position - transform.position;
Vector3 dirVecR = player.transform.position - transform.position;
rigidL.AddForce(dirVecL.normalized * 5, ForceMode2D.Impulse);
rigidR.AddForce(dirVecR.normalized * 5, ForceMode2D.Impulse);
}
curShotDelay = 0;
}
void reload()
{
curShotDelay += Time.deltaTime;
}
이때 적 전투기의 총알이 플레이어의 위치 좌표를 읽고 그 위치로 쏘아져야 하는데, 그러기 위해선 플레이어의 위치정보가 필요합니다. Enemy 스크립트에 Player를 맵핑하면 될 것 같지만, 프리펩(적 전투기)은 하이라키의 게임 오브젝트에는 접근하지 못하고, 같은 프리펩만 접근 할 수 있으므로 Enemy 스크립트에 바로 Player를 맵핑할 수 없습니다. 따라서 GameManager 스크립트에 Player를 맵핑 하고(게임 매니저 오브젝트는 인스턴스화 되어있기 때문에 접근 가능), 적 전투기가 생성될 때 Enemy 스크립트의 Player 변수에 GameManager의 Player변수를 복사해주겠습니다.
void spawnEnemy() {
//Enemy Spawn
int ranEnemy = Random.Range(0, 3);
int ranPoint = Random.Range(0, 9);
GameObject enemy = Instantiate(enemyObjs[ranEnemy], spawnPoint[ranPoint].position, spawnPoint[ranPoint].rotation);
Enemy enemyScript = enemy.GetComponent<Enemy>();
enemyScript.player = player; //적 전투기 생성 시, 플레이어 오브젝트 정보를 복사해 넘겨줌
Rigidbody2D rigid = enemy.GetComponent<Rigidbody2D>();
.
.
.
}
Enemy 스크립트에도 player를 담을 변수 추가
마지막으로, 플레이어 피격 이벤트를 구현하겠습니다.
Player 스크립트에 GameManager 변수를 추가하고 맵핑합니다.
public GameManager gm;
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "Border")
{
...
}
else if (collision.gameObject.tag == "Enemy" || collision.gameObject.tag == "EnemyBullet") {
gameObject.SetActive(false); //플레이어 비활성화
gm.respawnPlayer(); //맵핑한 GameManager의 함수 호출
}
}
OnTriggerEnter2D에 적 전투기 또는 적 총알과 콜라이더 충돌했을 때 로직을 작성합니다.
플레이어가 비활성화가 되면 그 아래 로직이 정상적으로 작동하지 않으므로, GameManager에 대신 작성해서 호출하는 방식으로 구현합니다.
GameManager 스크립트에 아래 코드 추가
public void respawnPlayer() {
Invoke("respawnPlayerExe", 2f);
}
void respawnPlayerExe()
{
player.transform.position = Vector3.down * 3.5f; //플레이어 리스폰 위치
player.SetActive(true); //플레이어 활성화
}
결과
'종스크롤 슈팅게임(1942)' 카테고리의 다른 글
6. 아이템과 필살기 구현하기 (0) | 2022.01.20 |
---|---|
5. 간단한 UI 만들기 (0) | 2022.01.19 |
3. 적 전투기 만들기 (0) | 2022.01.18 |
2. 플레이어 총알 구현 (0) | 2022.01.18 |
1. 플레이어 이동 & 맵 경계선 설정 (0) | 2022.01.17 |