1. 개요

Unity3D에서 Physics.Raycast는 물리 엔진을 활용해 광선을 발사하고, 광선과 충돌한 오브젝트를 탐지하는 데 사용됩니다. 이 기능은 다양한 게임 시스템에서 유용하게 활용될 수 있습니다. 예를 들어, 적 탐지, 아이템 상호작용, 발사체의 경로 계산 등 다양한 사례에서 활용 가능합니다.


2. 개념 설명

Physics.Raycast는 UnityEngine.Physics 클래스의 정적 메서드로, 다음과 같은 형태로 사용됩니다:

bool Physics.Raycast(Vector3 origin, Vector3 direction, float maxDistance, int layerMask);

주요 매개변수:

  1. origin: 광선이 시작되는 위치 (Vector3).
  2. direction: 광선이 발사되는 방향 (Vector3).
  3. maxDistance: 광선의 최대 탐지 거리 (float).
  4. layerMask: 광선이 탐지할 레이어를 지정 (int, 선택적).

반환값:

  • 충돌 여부를 나타내는 bool 값을 반환합니다. 만약 광선이 충돌하면 true, 아니면 false를 반환합니다.

RaycastHit 구조체:

충돌한 오브젝트에 대한 세부 정보를 얻으려면 RaycastHit 구조체를 활용합니다:

RaycastHit hitInfo;
if (Physics.Raycast(origin, direction, out hitInfo, maxDistance))
{
    Debug.Log($"Hit Object: {hitInfo.collider.name}");
}

LayerMask란?

LayerMask는 Unity에서 특정 레이어에 속한 오브젝트를 선택적으로 탐지하도록 설정하는 데 사용됩니다. int 타입으로 처리되며, 비트마스크 형식으로 동작합니다. LayerMask.GetMask() 메서드를 사용하여 특정 레이어를 참조하거나 ~ 연산자를 통해 특정 레이어를 제외할 수도 있습니다.


3. 활용 예

3.1 카메라 중심에서 오브젝트 클릭 감지

다음 코드는 카메라의 중심에서 광선을 발사해, 오브젝트를 클릭했는지 확인하는 간단한 예입니다:

void Update()
{
    if (Input.GetMouseButtonDown(0)) // 마우스 왼쪽 버튼 클릭
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out RaycastHit hitInfo, 100f))
        {
            Debug.Log($"Clicked on: {hitInfo.collider.name}");
        }
    }
}

3.2 적 탐지 시스템

플레이어가 정면에서 적을 감지하는 간단한 예제입니다:

public Transform player;
public float detectionRange = 10f;
public LayerMask enemyLayer;

void Update()
{
    Ray ray = new Ray(player.position, player.forward);
    if (Physics.Raycast(ray, out RaycastHit hitInfo, detectionRange, enemyLayer))
    {
        if (hitInfo.collider.CompareTag("Enemy"))
        {
            Debug.Log("Enemy detected: " + hitInfo.collider.name);
        }
    }
}

3.3 환경 상호작용

광선을 사용해 플레이어가 바라보는 방향의 버튼을 활성화하는 예제:

public LayerMask interactableLayer;

void Update()
{
    Ray ray = new Ray(transform.position, transform.forward);
    if (Physics.Raycast(ray, out RaycastHit hitInfo, 5f, interactableLayer))
    {
        if (hitInfo.collider.CompareTag("Button"))
        {
            hitInfo.collider.GetComponent<Button>().Activate();
        }
    }
}

4. 주의점 혹은 특이점

  1. 레이어 관리:
    • layerMask를 사용해 특정 레이어의 오브젝트만 탐지하도록 제한할 수 있습니다. 이를 통해 불필요한 연산을 줄이고 성능을 최적화할 수 있습니다.
    int layerMask = LayerMask.GetMask("Enemy");
    if (Physics.Raycast(origin, direction, out hitInfo, maxDistance, layerMask))
    {
        Debug.Log("Enemy detected!");
    }
    • 비트마스크 연산을 사용해 여러 레이어를 탐지하거나 제외할 수 있습니다:
    • int layerMask = LayerMask.GetMask("Enemy", "Obstacle"); // Enemy와 Obstacle 레이어 포함 int excludedLayerMask = ~LayerMask.GetMask("IgnoreRaycast"); // IgnoreRaycast 레이어 제외
  2. 정확한 방향 설정:
    • 방향 벡터는 반드시 정규화(normalized)해야 올바르게 작동합니다.
  3. 성능 고려:
    • Raycast는 연산 비용이 높은 작업일 수 있습니다. 반복 호출이 필요한 경우 Batch Raycasting (Physics.RaycastAll)을 고려하세요.
  4. 콜라이더가 없는 오브젝트:
    • Raycast는 Collider가 없는 오브젝트와 충돌하지 않습니다. 따라서 탐지하려는 오브젝트에 Collider가 적용되어 있는지 확인하세요.

5. 결론

Physics.Raycast는 Unity의 물리 시스템에서 매우 강력한 도구입니다. 간단한 광선 추적부터 복잡한 물리 연산까지 다양한 활용이 가능합니다. 이를 적절히 활용하면 게임 내 상호작용과 동적 게임플레이를 한층 더 강화할 수 있습니다. 특히 LayerMask를 활용해 불필요한 연산을 줄이고 원하는 대상에만 효과적으로 광선을 적용하는 것이 중요합니다.

반응형

+ Recent posts