24.02.05 TIL - Unity : RayCast, 가상의 광선을 쏘아 물리적 충돌 감지

JJwoo·2024년 2월 5일
post-thumbnail

Physics.Raycast

  • 특정 지점에서 특정 방향으로 가상의 Ray 를 발사하고, 어떤 물체에 부딪히는지를 확인하는 데 사용
    (위치, 방향, 거리, 오브젝트 이름 확인 등)

  • 물리적 충돌 검출에 주로 사용되며, 예를 들어 총알이나 시선 등이 실제로 물체에 닿는지를 가상으로 시뮬레이션 할 때 유용

  • origin(시작점)에서 direction(방향)으로
    maxDistance 길이만큼 Ray를 쏜다.

  • Physics.Raycast는 bool 타입을 반환

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

Vector3형의 시작점과 방향을 가지고 있는 구조체

  • hitinfo 광선에 충돌되는 Collider 컴포넌트를 가진 객체에 대한 거리, 위치 등의 자세한 정보를 RaycastHit 에 저장
    (즉, Collider가 있어야 한다)
  • maxDistance 생략 시, default 값은 무한대 = 거리가 무한
  • layerMask : 특정 레이어에 속한 오브젝트만 검출하도록 필터링할 때 사용
  • layerMask 생략 시, default 값은 defaultRaycastLayers

  • hitInfo 생략 시, 충돌체에 대한 정보를 따로 저장하지 않음

  • 레이의 시작점이 콜라이더 내부에 있는 경우에는 그 콜라이더를 감지하지 않는다.

매개변수

-파라미터
origin레이가 시작되는 월드 좌표상의 지점
direction레이의 방향
maxDistance레이가 충돌을 확인해야 할 최대 거리
layerMask레이를 발사할 때 선택적으로 Collider를 무시하기 위해 사용되는 레이어 마스크
queryTriggerInteraction이 쿼리가 트리거를 감지해야 하는지 여부를 지정

예시) 투사체 없는 사격 구현

// 투사체가 없는 발사
// 화면 가운데서 시작하는 Ray 생성 ,  Viewport = 게임화면
Ray ray = Camera.main.ViewportPointToRay(new Vector2(0.5f, 0.5f));
// 1. Viewport 게임화면의 좌표를 기준으로, 왼쪽 아래는 0,0 이고 오른쪽 위는 1,1 이다.  즉 0.5, 0.5는 곧 화면의 중앙을 의미한다.
// 2. ScreenPointToRay() 메서드는 Screen 해상도 크기를 기반으로 하기 때문에 왼쪽 아래는 0,0 이지만 오른쪽 위는 해당 해상도의 길이이다.



// Ray에 맞은 물체를 담아둘 변수
RaycastHit hit;

// Ray를 발사하고 Ray에 맞은 물체는 변수 hit에 저장
Physics.Raycast(ray, out hit);
// Physics 클래스의 함수인 만큼 물리 작용을 이용하므로 Collider 컴포넌트가 있는 오브젝트만 Ray와 충돌이 가능

if (Physics.Raycast(ray, out hit))
{
    // 맞은 위치에, 맞은 표면의 수직이 되는 각도로 총 효과 프리팹 생성
    GameObject shootEffect = Instantiate(ShootEffectPref, hit.point + hit.normal * 0.01f, Quaternion.LookRotation(hit.normal));
    // hit.normal : Ray와 오브젝트가 충돌한 법선 각도, 방향을 나타내는 Vector3값이며 Ray가 바닥과 충돌하면 바닥과 수직이 되는 각도로 향함

    // 총 자국을 맞은 오브젝트의 자식으로 설정
    shootEffect.transform.SetParent(hit.transform);
}


// Ray에 맞은 물체가 적이라면
if (hit.transform.tag == "Enemy")
{
    hit.transform.SendMessage("Damaged", 10); // 적에게 10만큼 공격받으라 전달
    // SendMessage를 사용하여 간접적으로 Damaged 함수 호출
}

ViewportPointToRay

  • 카메라의 뷰포트를 기준으로 레이를 발사

  • 0에서 1 사이의 값, 왼쪽 하단이 (0,0)이고 오른쪽 상단이 (1,1)

  • 절대값이라 다양한 해상도에서도 동일한 결과를 얻을 수 있다.

화면의 특정 비율 위치에 기반한 상호작용에 사용, 플레이어의 시야 중앙에서 총알이나 다른 투사체를 발사하는 경우에 적합



ScreenPointToRay

  • 화면의 특정 지점에서 3D 공간으로 레이를 발사할 때 사용

  • 카메라의 시점에서 화면의 특정 좌표를 기준으로 레이를 생성.

  • 화면 좌표는 픽셀 단위로, 화면의 왼쪽 하단이 (0,0)이고 오른쪽 상단이 사용 해상도의 크기가 된다.

마우스 클릭으로 오브젝트를 선택할 때 사용, 화면상에서 클릭한 정확한 지점으로부터 레이를 발사해야 할 때 유용


투사체를 실제로 발사하지 않고도 사격 효과를 구현 할 때 주로 사용.

FPS(First-Person Shooter) 또는 TPS(Third-Person Shooter) 게임에서 매우 유용하게 사용되는 기능.

플레이어가 적을 조준하고 발사 버튼을 누를 때, 화면 중앙 또는 조준점에서 레이를 발사하여 적중 여부를 판단하고, 맞춘 경우 적에게 데미지를 주거나 상호작용을 하는 등의 게임 로직을 구현하기 좋다.

profile
개발 모코코

0개의 댓글