본문 바로가기

unity3d

Physics.Raycast 활용하여 3D 공간에서 충돌 체크하기

Ray Cast 란, 3차원 공간에서 어느 한 점(시작점)에서 Ray 를 정해진 방향(direction vector)으로 쏴 Ray 와 충돌 되는 객체를 구하는 방법을 말합니다. 


Unity3D 에서는 Ray Cast 를 위한 몇가지 유용한 클래스와 struct, 메소드 등을 제공합니다. 

샘플 구현에 필요한 몇가지를 우선 소개 하자면,


Ray (struct)  > Unity Script Reference 참고

Ray Cast를 위한 재료 중 가장 중요한 Ray 의 정보를 담습니다.

origin : Ray 가 시작되는 지점을 설정하고,

direction : Ray 가 시작 지점(origin)에서 쏘여지는 방향을 설정합니다.


Physics.Raycast (Physics class, Raycast Method)  > Unity Script Reference 참고

Ray Cast 를 실행하여 Ray 와 객체가 충돌하는 지 체크하는 메소드입니다.

객체와 충돌 되는 경우 true 값을 반환합니다. 


RaycastHit (struct)  > Unity Script Reference 참고

Physics.Raycast 메서드의 파라미터로 값을 할당(out)하며 Ray 에 충돌 된 객체의 정보를 담습니다.



그럼, 직접 샘플을 통해 Ray Cast 를 구현 해 보겠습니다. Ray Cast는 다양한 방법으로 이용 될 수 있겠지만, 우선 저는 스크린에서 마우스 버튼이 Up 될 때 마다 그 지점에서 Ray를 쏴 객체와 충돌하는지 체크하는 샘플로 Ray Cast 구현 방법을 설명 해 보겠습니다.



1. Ray 객체 생성

- Mouse 가 Up 될 때마다 실행 되야 하기 때문에 Input.GetMouseButtonUp() 를 체크하여 그 때 마다 Ray 객체를 생성합니다.

public Camera MainCamera;
    
// Update is called once per frame
void Update () {

    if (Input.GetMouseButtonUp(0)) {
        // Ray 객체 생성
        Ray ray = MainCamera.ScreenPointToRay(Input.mousePosition);

        // rayCasting 실행
        rayCasting(ray);
    }
}


- MainCamera (Inspector 상에서 할당했습니다.) 의 ScreenPointToRay 메서드는 Screen 상에서의 좌표를 World space 상에서의 좌표로 변환하여 시작점(origin)으로 설정하고, direction 을 카메라가 비추는 방향으로 설정 된 Ray 객체를 반환합니다.



2. Ray Cast 실행

void rayCasting(Ray ray) {
    RaycastHit hitObj;
    if (Physics.Raycast(ray, out hitObj, Mathf.Infinity)) {
        if (hitObj.transform.tag.Equals("Cube")) {
            CubeScript cubeScript = hitObj.transform.GetComponent<CubeScript>();
            if (null != cubeScript) {
                cubeScript.Hit();
            }
        }
    }
}


- Physics.Raycast 메서드를 실행하면, Ray 객체의 origin에서 direction 으로 Ray 를 쏴 줍니다. 그리고, 충돌 되는 객체가 있으면 true 를 반환하고 RaycastHit 객체를 out 키워드를 통해 파라미터로 던져 주면 충돌 된 객체의 정보를 담아서 반환 해 줍니다. 


- 메서드 실행 시 Ray의 길이를 float 값으로 받습니다. 이 값은 Ray 가 얼마만큼(길이만큼) 쏴 지도록 설정하는 것인데, Mathf.Infinity를 할당하면 무한대로 쏴서 체크합니다.



3. Ray 에 맞은 객체 처리 구현

- Cube 를 Prefab 으로 만든 뒤에 Tag에 "Cube"라고 입력 하고, Cube 객체를 컨트롤 할 CubeScript 를 컴포넌트로 추가했습니다.

- CubeScript 에서 Hit 메소드를 만들어 Ray에 맞았을 경우 호출 하도록 합니다.

float angle = Random.Range(270, 360);
this.gameObject.transform.Rotate(Time.deltaTime * angle * Vector3.one);





 Sample Project


RaycastingSample.7z





Sample Video