Unity 강의/Unity Course(2) - 절대강좌! 유니티

[Unity Course 2] 05. 총 발사 로직 5

첨부엉. 2024. 6. 20. 18:09
반응형
위키북스 출판사 이재현 저자님의 '절대강좌! 유니티' 책을 참고하여 필기한 내용입니다.

 

텍스처 변경하기 - 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

반응형