[Unity Engine] 유니티 엔진 게임 개발 일지 #5

신형석·2023년 3월 16일
0

게임 개발 일지

목록 보기
5/10

이번 게시글에서는 적을 만들고, 적의 일정 범위 내로 들어가면 플레이어를 향해 총을 쏘는 코드를 짜보겠다.

컨셉은 이렇다.

  1. 플레이어가 일정 범위 안에 들어오는 경우,
  2. 적은 그때부터 텀을 두고 bullet을 발사한다.

컨셉은 간단하다. 코드로 짜보도록 하겠다.

우선 1. 플레이어가 일정 범위 안에 들어오는 경우, 를 짜보도록 하겠다.

적 주변에 일정 크기의 Circle Collider2D를 만든 후, Is Trigger 옵션을 켜준다. 이로서 이 Collider는 Trigger로 작동하게 된다.

void OnTriggerStay2D(Collider2D other) {
    if (other.tag == "Player"){
        Debug.Log("Player");
    }
}

OnTriggerStay2D를 사용하여, 특정 오브젝트가 Trigger 안에 존재할 경우 Debug.Log를 출력한다.

이로서 Player를 감지하는 코드는 작성하였다. 이제 2. 적은 그때부터 텀을 두고 bullet을 발사한다. 를 작성해보도록 하겠다.

이 코드를 작성하기 위해서는 유니티의 코루틴(Coroutine)의 개념을 알아야 한다. Unity Documentation에서의 코루틴 설명을 원하면, 이곳을 참고하길 바란다.

Update 함수는 멈추지 않고 안의 명령문을 계속 실행한다. 하지만, 특정 시간에서만 돌아가는 함수를 Update 함수 안에 작성하는 것은 비효율적인 일이다. 이럴 때 필요한 것이 코루틴이다.

코루틴은 일시적인 동작 등을 구현하고, 다른 작업이 처리될 때까지 기다리는 기능이 필요할 때 사용한다. 작성자는 적의 총알은 텀을 두고 발사하는 기능을 구현하고 싶었으므로, 코루틴을 선택하게 되었다.

우선 코드 전체를 모두 첨부하겠다.

[SerializeField] GameObject enemyBulletPrefab;
[SerializeField] GameObject enemyShotPos;
[SerializeField] float bulletSpeed = 1f;
[SerializeField] GameObject player;
Vector3 playerPos;
bool isAttacking = false;
Vector3 dir;

void OnTriggerStay2D(Collider2D other) {
    if (other.tag == "Player"){
        Debug.Log("Player");
        playerPos = other.transform.position;
        StartCoroutine("BeforeAttack");
    }
}

IEnumerator BeforeAttack(){
    if(isAttacking == false){
        isAttacking = true;
        yield return new WaitForSeconds(1f);
        StartCoroutine("Attack");
    }
}
IEnumerator Attack(){
    GameObject enemyBullet = Instantiate(enemyBulletPrefab);
    enemyBullet.transform.position = enemyShotPos.transform.position;
    dir = player.transform.position - enemyBullet.transform.position;
    enemyBullet.gameObject.GetComponent<Rigidbody2D>().AddForce(dir * bulletSpeed, ForceMode2D.Impulse);
    yield return new WaitForSeconds(1f);
    isAttacking = false;
}

코루틴을 시작하려면, StartCoroutine()을 사용하면 된다. 괄호 안에는, 시작하고 싶은 코루틴 이름을 적어주면 된다. 우선, Trigger가 발동되었을 경우 BeforeAttack 함수를 불러오게 하였다.

코루틴의 반환형은 IEnumerator로 설정한다. 그리고 이 함수의 리턴은, return으로 그냥 사용하는 것이 아닌 yield return을 사용한다. 또한, yield return 이후 특정 명령문을 사용하여 Invoke와 같은 효과를 낼 수 있다.

yield return null

을 사용한다면, 1 프레임만큼 멈춘다는 뜻이고

yield return new WaitForSeconds(숫자)

를 사용한다면, 숫자 초 만큼의 시간을 멈춘 후 다시 실행한다.

첫 isAttacking은 false로 정해져있다. 그러므로 코루틴을 실행했을 때, if문 안으로 들어가 true로 바뀐 후 1초간 기다린 다음 Attack을 실행한다. Attack은 이전 게시글에서 만든 총알 발사 알고리즘과 비슷하고, 모든 작업을 끝낸 후 isAttacking을 다시 false로 바꿔준다.

이렇게 적을 감지하여 총알을 쏘게 하는 알고리즘까지 만들어보았다. 제작된 영상은 이곳에서 확인할 수 있다.

구현할 기능이 엄청 많지만, Tank Hero 2D는 여기까지 할 생각이다. 이제 3D로 넘어가서, 조금 더 게임같이 만들어 볼 생각이다.

0개의 댓글

관련 채용 정보