본문 바로가기

[Unity] 레이캐스트(Raycast)

·
2019. 12. 3. 17:54
반응형

레이캐스트는 광선을 쏘는 것을 의미합니다. 여기서는 레이를 쏜다 라고 표현하겠습니다.
레이캐스트를 사용하면 광선에 충돌되는 콜라이더(Collider)에 대한 거리, 위치 등의 자세한 정보를 RaycastHit로 반환합니다. 레이캐스트는 충돌되는 콜라이더를 반환하므로 콜라이더가 없는 게임오브젝트는 충돌을 감지할 수 없습니다. 레이캐스트는 주로 전방에 있는 오브젝트를 검출할 때 사용합니다. 다양한 레이캐스트 함수가 있지만 몇가지만 살펴보겠습니다.

Physics.Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo)

시작점(origin)방향(direction)으로 레이를 쏘는 함수입니다. 시작점과 방향으로 모든 충돌체에 대해 레이를 쏩니다.
충돌이 되면 true를 반환하고 RaycastHit로 충돌정보를 넘겨줍니다.

다음은 레이캐스트의 예제 코드입니다.

public class RaycastExample : MonoBehaviour {

    private RaycastHit hit;

    void Update () 
    {
        if (Physics.Raycast(transform.position, transform.forward, out hit))
        {
            Debug.Log("hit point : " + hit.point + ", distance : " + hit.distance + ", name : " + hit.collider.name);
            Debug.DrawRay(transform.position, transform.forward * hit.distance, Color.red);
        }
        else
        {
            Debug.DrawRay(transform.position, transform.forward * 1000f, Color.red);
        }
    }
}

Physics.Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance)

시작점(Origin)방향(Direction)으로 최대거리(maxDistance)만큼 레이를 쏘는 함수입니다. 최대거리 안에서 충돌이 되면 true를 반환하고 RaycastHit로 충돌정보를 넘겨줍니다.

다음은 레이캐스트의 예제 코드입니다.

public class RaycastExample : MonoBehaviour {

    private RaycastHit hit;
    private float maxDistance = 300f;

    void Update () 
    {
        if (Physics.Raycast(transform.position, transform.forward, out hit, maxDistance))
        {
            Debug.Log("hit point : " + hit.point + ", distance : " + hit.distance + ", name : " + hit.collider.name);
            Debug.DrawRay(transform.position, transform.forward * hit.distance, Color.red);
        }
        else
        {
            Debug.DrawRay(transform.position, transform.forward * 1000f, Color.red);
        }
    }
}

Physics.Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask)

시작점(Origin)방향(Direction)으로 최대거리(maxDistance) 만큼 레이어마스크(layerMask)만 필터링해서 레이를 쏘는 함수입니다. 레이어마스크 값에 해당하는 레이어가 아니면 충돌이 되더라도 검출되지 않습니다. 충돌이 되면 true를 반환하고 RaycastHit로 충돌정보를 넘겨줍니다.

이해를 돕기위해 특정 레이어만 검출하는 예를 들어보겠습니다. 다음과 같이 유니티에서 8 : Green, 9 : Blue로 레이어를 설정하였습니다.

빨간색 구는 레이를 쏘는 오브젝트이고 왼쪽부터 사각형, 구, 캡슐을 배치했습니다. 사각형, 캡슐은 Green 레이어를 설정했고 구는 Blue 레이어를 설정했습니다.

다음은 Green 레이어만 검출하는 예제 코드입니다.

public class RaycastExample : MonoBehaviour {

    private RaycastHit hit;
    private int layerMask;

    void Start()
    {
        // 레이어 인덱스가 8인 레이어마스크 변수에 대입. 
        // 8만큼 Bit Shift
        layerMask = 1 << 8;
    }

    void Update () 
    {
        // 레이어 인덱스가 8인 레이어 마스크만 검출
        if (Physics.Raycast(transform.position, transform.forward, out hit, Mathf.Infinity, layerMask))
        {
            Debug.Log("Hit Green " + hit.collider.gameObject.name);
            Debug.DrawRay(transform.position, transform.forward * hit.distance, Color.red);
        }
        else
        {
            Debug.DrawRay(transform.position, transform.forward * 1000f, Color.red);
        }
    }
}

Physics.Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance)

인자로 받은 레이(ray)의 정보를 가지고 최대거리(maxDistance) 만큼 레이를 쏘는 함수입니다 Ray는 시작점(origin)방향(direction)을 가지고 있는 클래스입니다. 충돌이 되면 true를 반환하고 RaycastHit로 충돌정보를 넘겨줍니다.

다음은 스크린에서 마우스 왼쪽 버튼 클릭 시 스크린에서 월드 공간으로 레이를 쏘는 예제 코드입니다.

public class RaycastExample : MonoBehaviour {

    private Ray ray;
    private RaycastHit hit;

    void Update()
    {
        ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        if(Input.GetMouseButton(0))
        {
            if (Physics.Raycast(ray, out hit, 1000f))
                Debug.DrawRay(ray.origin, ray.direction * 1000f, Color.red);
        }
    }
}

참고

반응형
블로그 이미지
Frontend Engineer

댓글