유니티(Raycast & LayerMask)

1 minute read

Raycast

  1. 광선을 쏴서 충돌되는 물체가 있는지 검사
  2. 게임 속 물체를 클릭하는건 클릭한 화면의 위치로 부터 레이저를 쏴 닿은 물체가 있는지 확인하는것
  3. 하나의 물체가 닿으면 그 뒤에 물체는 관통x
    void Update()
    {
        RaycastHit hit;

        Vector3 look = transform.TransformDirection(Vector3.forward);
        // 로컬 좌표로서의 (0, 0, 1)을 월드 좌표로 변환하여 리턴함

        Debug.DrawRay(transform.position, look * 10, Color.red); 
        // transform.position 에서 빨강색 광선을 (transform.position + look * 10) 위치까지를  쏜다. 
        // DrawRay 는 Raycast 와 다르게 두번째 인수가 방향만을 나타내는건 아니라 크기도 필요함.
        // Raycast 와 다르게 start에서 dir 방향으로 쏘는게 아니라 start부터 start+dir 위치까지를 쏘고 이를 시각적으로 그림

        if (Physics.Raycast(transform.position + Vector3.up, look))
        {
            Debug.Log("Raycast!");
        }
        if(Physics.Raycast(transform.position + Vector3.up, look, 20))
        {
            Debug.Log("Raycast!");
        }
        if(Physics.Raycast(transform.position + Vector3.up, look, out hit, 20))
        {
            Debug.Log("Raycast!");
        }
    }
  • transform.position + Vector3.up 위치로부터 광선을 쏜다.
    • Vector3.up 을 더해준 이유는 이 스크립트의 주인 오브젝트의 Pivot이 발에 가있어서 그냥 transform.position 에서 쏘면 광선이 발에서 나가므로, 조금 위에서 광선을 쏘기 위해 (0, 1, 0)만큼을 더해주었다. (Vector3.up)
  • transform.TransformDirection(Vector3.forward) 방향으로 광선을 쏜다.
    • 로컬 좌표로서의 (0, 0, 1)를 월드 좌표로 변환한 것.
    • 즉, 이 스크립트의 주인 오브젝트 기준에서의 앞 방향이 월드 좌표계로 변환된 것
      • 광선의 시작 위치와 방향을 월드 좌표 기준으로 설정해 주어야 하니까
  • 광선에 충돌한 오브젝트의 정보는 hit에 담긴다.
    • position, normalized 등등 충돌한 오브젝트의 위치 방향 등등의 정보가 담긴다.
    • RaycastHit hit;

Raycast가 관통되게 하는 법

RaycastHit[] hits;
hits = Physics.RaycastAll(transform.position + Vector3.up, look, 20);

LayerMask

  • 특정 오브젝트들에 대해서만 Raycasting, 카메라 렌더링시 사용하는 CullingMask등등의 물리 처리르 하기 위해 사용
  • 특정 오브젝트에 Layer를 붙이면 그 대상으로만 Raycasting처리 가능
  • 특정 오브젝트만 제한하므로 부하를 줄이고 성능을 높일 수 있음

LayerMask는 int이고 비트 플래그로 사용됨

GitHub Logo

  • LayerMask는 32 비트의 int형
    • 비트 플래그로, 비트로 각각의 아이템을 상징하며 구분
    • 몬스터는 10000000 8번 레이어(1 « 8)
  • LayerMask는 32개까지 가능
     int mask = (1 << 8); // 8 번 레이어 
     int mask2 = (1 << 8) | (1 << 9); // 8 번 레이어 + 9 번 레이어
     LayerMask mask3 = LayerMask.GetMask("Monster") | LayerMask.GetMask("Wall") // int mask = (1 << 8) | (1 << 9); 와 동일
      RaycastHit hit;
      if (Physics.Raycast(ray, out hit, 100.0f, mask))
      {
          Debug.Log(hit.collider.gameObject.name);
      }
    
  • 그외로 Tag가 있으나 별 기능은 없지만 추가적으로 오브젝트들을 그룹지어 구분해줌
    GameObject.FindGameObjectWithTag("Monster");
    Debug.Log(hit.collider.gameObject.tag);
    
    1. LayerMask와 Tag의 차이
    • LayerMask
      • int크기의 비트
      • 32개까지만 가능
      • 물리적인 처리에 대한 여부
    • Tag
      • 만들수있는 갯수 제한x
      • 이름과 같이 문자열로서 그룹지음

Leave a comment