7. 발사체 제작(1)

MOON·2022년 7월 18일
0

유니티_3D_SpaceShooter

목록 보기
7/11
post-thumbnail

총알 발사 방식

Projectile 방식
총알이 물리적으로 발사되는 방식으로 총알이 직접 날아가 적에게 타격을 입힌다. 따라서 당연히 총알이 시각적으로 표현되지만, 짧은 시간동안 여러개의 총알을 생성하게 되면 게임의 속도가 저하되는 단점이 있음. 따라서 총알은 일반적으로 로우폴리모델이나 Panel Mesh 모델에 텍스쳐를 입혀 사용한다. 총알 역시 동적으로 생성하기 보다는 오브젝트 풀(Object Pool)개념을 도입해 총알을 미리 생성해두고 번갈아 가며 발사되도록 구현하는 편이 속도 향상에 유리하다

Ray Casting 방식
FPS게임에서 저격용 총의 발사 루틴을 구현하는데 자주 활용된다. 실제 총알이 발사되는 방식이 아니라 레이저 빔과 같이 눈에 보이지 않는 선을 발사해 적 또는 물체를 검출하는 방식임. 즉, 총을 쏘면 총구 화염이 표시됨과 동시에 멀리 떨어져 있는 적이 피격되는 효과를 연출할 수 있다.


총알 모델 준비

실습 자료에서 “Resource/Models/Bullet.unitypackage를 임폴트함
Project뷰의 05.Models폴더로 이동

3D Max에서 제작한 총알은 90도 회전한 서 있는 모델임. 3D Max에서 90도 회전한 다음에 Export하여 유니티에서 적용
유니티에서 빈게임 오브젝트를 만들고 이 빈 오브젝트에 차일드화 한 후 총알 오브젝트를 90도 회전 시킴

빈 게임 오브젝트 생성 : Bullet , 위치(0, 0, 0)
Bullet 게임 오브젝트에 lowpolybullet모델을 차일드 화
위치 (0, 0, 0), 회전 (90, 0, 0) - 유니티의 좌표계와 맞춤 (회전은 lowpolybullet에다가 적용함)
FBX파일이 3DMAX에서 제작한 좌표축과 틀림



충돌 처리

Rigidbody

유니티에서 게임 오브젝트를 이동할 때 보통 Transform의 Position 속성을 이용하거나 Rigidbody컴포넌트를 추가해 물리 시뮬레이션을 이용함
Rigidbody컴포넌트를 게임오브젝트에 추가하면 해당 게임오브젝트는 물리엔진의 영향을 받음
Bullet을 선택한 후 Component > Physics > Rigidbody 추가
Gravity 속성 : Use Gravity 속성을 끔
실행하면 총알이 아래로 떨어지는것을 확인할 수 있음


Rigidbody 속성


BulletCtrl.cs 스크립트 컴포넌트를 하나 만든다.
Bullet게임오브젝트에 추가

파괴력, 힘 변수를 선언하고, Rigidbody 컴포넌트를 저장할 rb변수를 선언합니다.
Start() 함수는 스크립트가 실행되면 제일 처음으로 수행되는 함수이며, 총알이 생성됨과 동시에 forward 방향으로 날아가게 됩니다.


물리엔진 속성 설정
물리 기능의 설정 : Physics Manager를 통해 설정 가능함
메뉴 : Edit > Project Settings > Physics

Collider 컴포넌트

Collider컴포넌트는 충돌을 감지하는 일종의 센서
Box Collider - 가장 일반적인 충돌 체크 (건물등에 사용)
Sphere Collider - 가장 처리속도가 빠름
Capsule Collider - 주로 Player나 적 캐릭터의 충돌체로 사용할 때가 많음
Mesh Collider - 충돌 감지를 위한 CPU부하가 제일 많은 Collider
Wheel Collider - 차량의 바퀴에 사용할 목적으로 제공되는 Collider
Terrain Collider - 지형의 충돌을 위한 Collider


충돌 감지 조건

충돌을 감지하기 위해서는 아래 2가지 조건을 만족해야 함

총알 콜라이더 추가
Bullet 빈 게임 오브젝트를 선택한 후
Component > Physics > Sphere Collider 추가 (Radius : 0.2)

벽 콜라이더 추가
Wall은 원시 모델(Cube)를 사용했고, 원시 모델은 기본적으로 콜라이더가 추가 되어 있다. (Box Collider)


충돌 이벤트

모든 Collider컴포넌트에는 IsTrigger 속성이 있음

On : 충돌 체크는 하지만 물리적 현상은 일어나지 않음 (체크함)
물체가 서로 부딪혀 정지하거나 튕기는 물리적 현상을 일으키지 않음, 단순히 감지만 할 뿐임 (총알이 벽을 뚥고 지나가지만 충돌이 됐다라는것을 알 수 있다)
OnTrigger~~ 함수가 발생


Off : 충돌 체크도 하면서 물리적 현상이 일어남(기본값)
정지하거나, 튕기는 현상이 발생
OnCollision~~ 함수가 발생

태그 활용

벽에 총알이 날라 올 경우 어떤 Collider컴포넌트를 가진 오브젝트가 날라오는지를 판별 해야 함
판별의 식별자로 태그를 활용할 수 있음 (C#의 Hash Table 기능)
Edit > Project Setting < Tags & Layers 에서 태그를 하나 만들고 이름을 BULLET
Bullet게임 오브젝트에 태그를 설정


지금까지 만든 총알을 프리펩에 등록
기존에 Hierarchy View에 있던 Bullet은 제거


총알 삭제 스크립트 작성

RemoveBullet.cs 스크립트 작성 : 총알이 벽에 부딪쳤을 때 총알 삭제 로직
Wall 의 프리팹에 등록
모든 4개의 벽에 일괄적으로 스크립트가 적용됨

Trigger을 off로 해놓아서 Collision 함수가 발생합니다. 인자값으로 Collision coll은 충돌한 게임오브젝트의 정보, 충돌 위치, 충돌 속도 등의 정보가 있다.

만약 BULLET라는 태그를 가진 오브젝트일 경우 Destroy함수를 통해 삭제시킨다.


총알 발사 로직

(1) 총알 발사 위치 만들기
(2) 발사 이벤트 감지하기
총알 발사 위치를 시각적으로 표현하기 위한 기즈모 구현

  • Create Empty 오브젝트를 만듬 (이름 : FirePos), Player밑에 자식으로 추가
  • MyGizmo 스크립트 작성
  • FirePos에 등록


기즈모의 색상과 모양을 Inspector 뷰에서 직접 선택 가능
FirePos의 위치를 총구 앞으로 정확하게 위치 시키자

실행 모드에서 FirePos 위치를 총구 앞에 위치시킨다.
실행 모드에서 위치한 FirePos의 Transform 에다 마우스 오른쪽 버튼 Copy Component 한 다음 실행 보드 를 끄고 Transform 콤포넌트에 붙혀 넣기
만약 위치 잡기가 힘들면 아래 Transform 과 같이 셋팅 하도록 한다.


FirePos 를 하이어라키 뷰에서 총구 자식으로 옮겨 놓는다.
FireCtrl 스크립트를 만든 후 Player에 등록

bullet 프리펩을 할당할 변수, 총 발사 위치를 저장할 변수를 선언한다.
만약 마우스 왼쪽 버튼을 누르면 Fire()함수가 실행된다.
bullet을 Instantiate()함수를 통해 복제한다.




총알 발사 궤적 만들기

Trail Renderer컴포넌트
메쉬를 동적으로 꼬리처럼 만들어 주는 컴포넌트
Bullet을 선택한 후 Component - Effects - Trail Renderer 를 선택

다운받은 리소스 파일에서 “Resources/Textures/Trail.png”를 04.Images/Materials/로 가져옴
새롭게 머터리얼을 하나 생성 : BulletTrail
BulletTrail의 쉐이더를 Legacy Shaders/Particles/Additive로 변경


Bullet 오브젝트의 이펙터 효과 변경하기
Time : 동적으로 생성한 메시의 지속시간, 값이 크면 긴 궤적을 만들 수 있고, 값이 작을 수록 궤적의 길이가 작아진다.
0.7로 셋팅
Width : 메시의 최대 높이를 지정(기본값은 1임)
Curved Editor를 통해 앞쪽과 끝부분의 넓이를 지정할 수 있음

Bullet 오브젝트의 이펙터 효과 변경하기
Min Vertex Distance : 생성하는 버텍스 간의 최소값을 설정(값이 작을 수록 조밀한 폴리곤을 생성)
색깔 지정
앞 부분은 찐하게 불투명으로 처리
뒤 부분은 점점 투명으로 처리



파티클 활용하기

벽에 총알이 충돌했을 때 불꽃이 튀는 효과를 구현
파티클 패키지 임폴트
메뉴 > Assets > Unity Particle Pack 5.x 임포트


임포트를 마치고 나면 오류가 나기도 하는데

위 사진처럼 업데이트를 통해 해결 가능하다.
이제 RemoveBullet.cs 스크립트를 수정하자.
총알이 벽에 충돌했을 때 스파크 현상은 벽에서 처리함

파티클을 할당할 변수를 선언한다.
여기서도 Bullet를 맞은 경우 Instantiate를 통해 동적으로 생성한다
이제 할당 하면 아래 사진같이 파티클이 동작한다.

이제 법선벡터를 활용한 튀는 방향을 정해보자.

4개의 벽에 총알을 발사하면 스파크 튀는 방향이 항상 일정하게 생성
법선벡터를 구한다음에 해당 방향으로 스크를 방향을 설정
법선벡터 : 두 물체가 충돌한 평면 또는 구면의 접점에서 수직인 벡터
GetContact(0) 첫번째 충돌지점의 정보 추출

파티클 속성 지정 (Duration : 0.3 / Looping 언체크)

동적으로 생성한 spark 프리펩을 일정시간 지난 후 강제 소멸

Destroy(sparkEffect, 0.5f);

0.5초 뒤에 강제 소멸시킨다.


이것으로 발사체 제작(1)을 마무리 하겠다.
profile
나만의 공간

0개의 댓글