[Unity] 자습서 4장 - 총 발사 로직(Mac)

2023. 2. 22. 20:36·개발/Unity

이번 장에서는 총알 발사 기능을 구현하고 충돌 처리 방법을 알아볼 것이다. 게임에서 총기류 발사는 크게 두 가지 방식이 있는데 Projectile 방식과 RayCasting 방식이다. Projectile 방식은 총알이 물리적으로 발사되어 직접 날아가 적에게 타격을 입히는 방식이다. Raycasting 방식은 레이저 빔과 같은 눈에 보이지 않는 광선을 발사해 적 또는 물체를 검출하는 방식이다(발사와 동시에 피격). 이번 장에서는 Projectile 방식으로 우선 구현하겠다.

 

총알 모델 삽입

우선 리소스에서 총알 모델을 추가해주고 빈 오브젝트에 자식으로 넣은 뒤 각도를 알맞게 적용해준다.

 

그 후 총알을 직선 방향으로 나아가게 하는 스크립트를 작성하여 Bullet 오브젝트에 연결해주었다.

public class BulletCtrl : MonoBehaviour
{
    // 총알의 파괴력
    public float damage = 20.0f;
    // 총알 발사 힘
    public float force = 1500.0f;

    private Rigidbody rb;

    void Start()
    {
        // Rigidbody 컴포넌트를 추출
        rb = GetComponent<Rigidbody>();

        // 총알의 전진 방향으로 힘(Force)을 가한다.
        rb.AddForce(transform.forward * force);
    }
}

실행을 해보면 시작과 동시에 총알이 앞으로 날아가는 모습을 확인할 수 있다. 스크립트에서 사용한 AddForce 함수는 월드 좌표 기준으로 힘이 가해지므로 bullet 오브젝트가 회전하더라도 항상 같은 월드 좌표의 Z축 방향으로 날아가게 된다. 만약 총알이 회전하여 그 방향으로 날아가게 하려면 (= 해당 게임오브젝트의 로컬 좌표를 기준으로 힘을 주려면) AddRelativeForce 함수를 사용해야 한다.

 

Collider 컴포넌트

다음으로 총알이 벽을 뚫고가지 않고 벽이나 다른 오브젝트에 닿았을 때 충돌 처리를 해주어야 한다.

 

Collider 컴포넌트는 충돌을 감지하는 일종의 센서라고 생각하면 된다. Collider는 여러가지 종류가 있는데 Box Collider, Sphere Collider, Capsule Collider, Mesh Collider, Wheel Collider, Terrain Collider 중 Sphere Collider 가 처리 속도가 가장 빨라 활용이 권장된다. 

 

충돌 감지 조건

오브젝트가 다른 오브젝트에게 충돌을 했는지를 감지하려면 다음의 두 가지 조건을 만족해야 한다.

  • 충돌을 일으키는 양쪽 게임오브젝트 모두 Collider 컴포넌트가 추가돼 있어야 한다.
  • 두 게임오브젝트 중 움직이는 쪽에는 반드시 Rigidbody 컴포넌트가 있어야 한다.

위 조건에 맞게 Bullet 오브젝트에 Sphere Collider 컴포넌트를 추가하고 크기에 맞게 Radius 속성을 0.2f로 수정하였다.

 

Wall 에는 기본으로 Box Collider가 추가되어 있어서 게임을 실행해보면 벽을 뚫고 갔던 총알이 벽에 충돌해 정지되는 모습을 확인할 수 있다.

 

충돌 이벤트

Collider 가 포함된 게임오브젝트 끼리 충돌이 발생하면 OnCollision 또는 OnTrigger 이벤트 함수가 발생한다. 모든 Collider 컴포넌트에는 Is Trigger 속성이 있는데, 이 속성을 체크하면 충돌 감지는 되지만 물리적인 충돌은 일어나지 않는다. ( ex. 감지 센서)

 

총알이 벽에 충돌했을때 어떤 오브젝트가 날아와서 충돌을 일으켰는지 알기 위해 bullet 오브젝트의 Tag를 추가해 줄 필요가 있다. 인스펙터 뷰 상단에 Tag에서 새로운 "BULLET" 태그를 생성해 준 뒤, 태그 설정을 해준다.

 

그리고 충돌 이벤트를 구현하기 위해 새로운 스크립트를 작성하고 OnCollisionEnter 함수 안에 Tag 값을 비교하여 총알이 벽에 맞으면 삭제되게 처리해준다.

public class RemoveBullet : MonoBehaviour
{

    // 충돌이 시작할 때 발생하는 이벤트
    private void OnCollisionEnter(Collision collision)
    {
        // 충돌한 게임오브젝트의 태그값 비교
        if (collision.collider.CompareTag("BULLET"))
        {
            // 첫 번째 충돌 지점의 정보 추출
            ContactPoint cp = collision.GetContact(0);

            // 충돌한 게임오브젝트 삭제
            Destroy(collision.gameObject);
        }
    }
}

다음으로는 마우스를 클릭했을 때 총알이 발사되게 하도록 마우스 왼쪽 버튼을 클릭했을 때 총알을 생성하도록(총알이 발사되는 스크립트는 이미 존재하므로) 하는 스크립트를 작성하였다.

void Update()
    {
        // 마우스 왼쪾 버튼을 클릭했을 때 Fire 함수 호출
        if (Input.GetMouseButtonDown(0))
        {
            Fire();
        }
    }

    void Fire()
    {
        // Bullet 프리팹을 동적으로 생성(생성할 객체, 위치, 회전)
        Instantiate(bullet, firePos.position, firePos.rotation);
    }

프리팹을 연결해 줄 public 변수를 선언해주고, 총구쪽 위치에서 총알을 생성하도록 해주었다.

Input.GetMouseButtonDown() 은 마우스 왼쪽 버튼이 눌렸을 때 실행되며 인자는 마우스 버튼의 종류(0: 왼쪽 버튼, 1: 오른쪽 버튼, 2: 가운데 버튼)를 나타낸다.

게임을 실행하면 마우스 왼쪽 버튼을 클릭하면 총알이 발사되어 앞에 있는 벽에 맞아 사라지는 모습을 확인할 수 있다.

 

총알 궤적 효과

다음은 총알이 날아가는 궤적효과를 주도록 Trail Renderer 컴포넌트를 활용할 것이다. bullet을 선택하고 Trail Renderer 컴포넌트를 추가하면 아래와 같은 화면을 볼 수 있다.

 

필자는 이미 텍스처와 색상, 지속시간, 궤적 모양을 변경한 상태이다. 가장 위쪽에 보이는 곡선으로 궤적의 시작 부분과 끝 부분의 굵기를 지정해 줄 수 있으며 Time 으로 지속시간을, Color로 궤적 색깔을 설정할 수 있다.

 

파티클 활용

다음으로는 총알이 벽이나 다른 오브젝트에 맞았을 때 불꽃이 튀는 효과를 줄 것이다. 파티클 리소스는 에셋 스토어의 "Unity Particle" 을 사용하였다. 총알이 튀는 효과는 총알이 충돌하였을 때 발생해야 하므로 충돌 처리를 한 스크립트에 코드를 추가하여 적용할 것이다.

// 스파크 파티클 프리팹을 연결할 변수
    public GameObject sparkEffect;

    // 충돌이 시작할 때 발생하는 이벤트
    private void OnCollisionEnter(Collision collision)
    {
        // 충돌한 게임오브젝트의 태그값 비교
        if (collision.collider.CompareTag("BULLET"))
        {
            // 첫 번째 충돌 지점의 정보 추출
            ContactPoint cp = collision.GetContact(0);

            // 충돌한 총알의 법선 벡터를 쿼터니언 타입으로 변환
            Quaternion rot = Quaternion.LookRotation(-cp.normal);

            // 스파크 파티클을 동적으로 생성
            GameObject spark = Instantiate(sparkEffect, cp.point, rot);
            // 일정 시간이 지난 후 스파크 파티클을 삭제
            Destroy(spark, 0.5f);

            // 충돌한 게임오브젝트 삭제
            Destroy(collision.gameObject);
        }
    }

GetContact 함수로 충돌 지점의 정보를 받아올 수 있으며 GetContatctPoint 함수의 반환 타입 중 point는 충돌 지점의 위치를 반환한다. 이제 게임을 실행해보면 총알의 궤적이 생기고 벽에 맞았을 때 불꽃이 튀는 효과를 볼 수 있다.

 

게임 실행 화면

 

 

 

 

다음 장에서는 총구 화염 효과 및 장애물 설치에 대해서 알아볼 것이다.

양이 많아서 한번에 이해가 되지는 않지만 블로그 정리가 복습에 큰 효과가 있는 것 같다.

'개발 > Unity' 카테고리의 다른 글

[Unity] 자습서 6장 - 적 캐릭터 구현  (0) 2023.02.28
[Unity] 자습서 5장 - 코루틴, 오디오  (0) 2023.02.24
[Unity] 자습서 3장 - 캐릭터 제작(Mac)  (0) 2023.02.21
[Unity] 자습서 2장 - 게임 스테이지 제작(Mac)  (0) 2023.02.21
[Unity] 자습서 1장 - Unity 시작하기(Mac)  (0) 2023.02.20
'개발/Unity' 카테고리의 다른 글
  • [Unity] 자습서 6장 - 적 캐릭터 구현
  • [Unity] 자습서 5장 - 코루틴, 오디오
  • [Unity] 자습서 3장 - 캐릭터 제작(Mac)
  • [Unity] 자습서 2장 - 게임 스테이지 제작(Mac)
Majangnan
Majangnan
  • Majangnan
    개발 모코코
    Majangnan
  • 전체
    오늘
    어제
    • 분류 전체보기 (55)
      • 개발 (54)
        • C# (10)
        • SQL (3)
        • Unity (8)
        • Unreal (10)
        • C++ (2)
        • Server (1)
        • DX11 (8)
        • 알고리즘 (11)
  • 블로그 메뉴

    • 홈
    • 방명록
    • 깃허브
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    언리얼
    3dlight
    백준
    블루프린트
    UnReal
    상속
    알고리즘
    코딩테스트
    dx3d
    Mecanim
    슈팅게임
    c++
    C#
    MAC
    Unity
    DX11
    sql
    blueprint
    프로그래머스
    DirectX11
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Majangnan
[Unity] 자습서 4장 - 총 발사 로직(Mac)
상단으로

티스토리툴바