[Unity Course 2] 05. 총 발사 로직 5
위키북스 출판사 이재현 저자님의 '절대강좌! 유니티' 책을 참고하여 필기한 내용입니다.
텍스처 변경하기 - Mesh Renderer
불규칙한 텍스처를 적용하는 로직 추가
using UnityEngine;
public class BarrelCtrl : MonoBehaviour
{
// 폭발 효과 파티클을 연결할 변수
public GameObject expEffect;
// 무작위로 적용할 텍스처 배열
public Texture[] textures;
// 하위에 있는 Mesh Renderer 컴포넌트를 저장할 변수
private new MeshRenderer renderer;
// 컴포넌트를 저장할 변수
private Transform tr;
private Rigidbody rb;
// 총알 맞은 횟수를 누적시킬 변수
private int hitCount = 0;
private void Start()
{
tr = GetComponent<Transform>();
rb = GetComponent<Rigidbody>();
// 하위에 있는 MeshREnderer 컴포넌트 추출
renderer = GetComponentInChildren<MeshRenderer>();
// 난수 발생
int idx = Random.Range(0, textures.Length);
// 텍스처 지정
renderer.material.mainTexture = textures[idx];
}
... 생략

난수를 발생시키는 함수인 Random.Range 는 시작과 종료 인자의 타입에 따라 반환되는 범위가 다
| 사용법 | 결괏값 |
| Random.Range(1.0f, 10.0f) | 1.0f ~ 10.0f 범위의 난수 발생 (max 까지가 범위) |
| Random.Range(1,10) | 1 ~ 9 범위의 난수 발생 (max -1 까지가 범위) |
폭발력 적용하기 - AddExplosionForce
폭발하는 순간 주변의 물체를 추출하는 방식으로 구현


BARREL 이라는 이름의 Layer를 새로 추가하고 Barrel Prefab에 레이어를 BARREL로 설정한다.
using UnityEngine;
public class BarrelCtrl : MonoBehaviour
{
// 폭발 효과 파티클을 연결할 변수
public GameObject expEffect;
// 무작위로 적용할 텍스처 배열
public Texture[] textures;
// 폭발 반경
public float radius = 10.0f;
// 하위에 있는 Mesh Renderer 컴포넌트를 저장할 변수
private new MeshRenderer renderer;
// 컴포넌트를 저장할 변수
private Transform tr;
private Rigidbody rb;
// 총알 맞은 횟수를 누적시킬 변수
private int hitCount = 0;
private void Start()
{
tr = GetComponent<Transform>();
rb = GetComponent<Rigidbody>();
// 하위에 있는 MeshREnderer 컴포넌트 추출
renderer = GetComponentInChildren<MeshRenderer>();
// 난수 발생
int idx = Random.Range(0, textures.Length);
// 텍스처 지정
renderer.material.mainTexture = textures[idx];
}
// 충돌 시 발생하는 콜백 함수
private void OnCollisionEnter(Collision coll)
{
if(coll.collider.CompareTag("BULLET"))
{
// 총알 맞은 횟수를 증가시키고 3회 이상이면 폭발 처리
if (++hitCount == 3)
ExpBarrel();
}
}
// 드럼통을 폭발시키는 함수
void ExpBarrel()
{
// 폭발 효과 파티클 생성
GameObject exp = Instantiate(expEffect, tr.position, Quaternion.identity);
// 폭발 효과 파티클 5초 후에 제거
Destroy(exp, 5.0f);
//// Rigidbody 컴포넌트의 mass를 1.0으로 수정해 무게를 가볍게 함
//rb.mass = 1.0f;
////위로 솟구치는 힘을 가함
//rb.AddForce(Vector3.up * 1500.0f);
// 간접 폭발력 전달
InDirectDamage(tr.position);
// 3초 후에 드럼통 제거
Destroy(gameObject, 3.0f);
}
void InDirectDamage(Vector3 pos)
{
// 주변에 있는 드럼통 모두 추출
Collider[] colls = Physics.OverlapSphere(pos, radius, 1 << 3);
foreach(var coll in colls)
{
// 폭발 범위에 포함된 드럼통의 Rigidbody 컴포넌트 추출
rb = coll.GetComponent<Rigidbody>();
// 드럼통의 무제를 가볍게 함
rb.mass = 1.0f;
// freezeRotation 제한값을 해제
rb.constraints = RigidbodyConstraints.None;
// 폭발력을 전달
rb.AddExplosionForce(1500.0f, pos, radius, 1200.0f);
}
}
}
드럼통을 기준으로 반경 10m에 있는 Collider 컴포넌트를 추출한다. 3번째 인자인 레이어는 비트 연산 표기 법을 이용해 3번째 레이어를 의미하는 1<<3을 사용
1<<3 을 이진수로 표현하면 2³ 이다.
인자에 10진수를 표기하지 않고 비트 연산자 표기법을 사용하는 이유는 다양한 논리 연산이 가능하기 때문
- 1<<8 | 1<<9 : or 연산, 8번 또는 9번레이어
- ~(1<<8) : NOT연산, 8번 레이어를 제외한 나머지 모든 레이어
Physics.OverLapSphere(원점, 반지름, 검출 대상 레이어)
Physics.OverlapSphere 함수의 반환 값은 조건에 맞고 해당 범위에 들어온 모든 Collider 컴포넌트가 배열에 담겨 넘어옴
// 주변에 있는 드럼통 모두 추출
Collider[] colls = Physics.OverlapSphere(pos, radius, 1 << 3);
Rigidbody.AddExplosionForce 함수의 인자는 다음과 같음.네 번째 인자를 생략하면 폭발력은 횡(가로방향)으로만 적용
Rigidbody.AddExplosionForce(횡 폭발력, 폭발 원점, 폭발 반경, 종 폭발력)
OverlapSphereNonAlloc
Physics.OverlapSphere 함수는 검출된 개수가 명확하지 않을 때만 사용해야됨 Garbage가 발생하기 때문
Physics.OverlapSphereNonAlloc 함수는 검출된 개수가 명확할 때 사용 권장, 결괏값을 저장할 정적 배열을 미리 선언해 사용, 실행중에 배열의 크기를 변경할 수 없음
Overlap계열의 함수
- OverlapBox
- OverlapBoxNonAlloc
- OverlapCapsule
- OverlapCapsuleNonAlloc
- OverlapSphere
- OverlapSphereNonAlloc