| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- Online Judge
- 독서
- BOJ
- Network Programming
- Toy Project
- Data Structure
- C++
- git
- multi-thread
- c#
- PS
- Unity
- System Programming
- Today
- Total
I'm FanJae.
[20260527] Unity 정리 ( Unity Raycast 응용 : LayerMask, Tag, Raycast를 이용한 상호작용 ) 본문
[20260527] Unity 정리 ( Unity Raycast 응용 : LayerMask, Tag, Raycast를 이용한 상호작용 )
FanJae 2026. 5. 27. 16:591. Raycast 복습
- Raycast는 시작 위치에서 특정 방향으로 광선을 발사한다.
- 이 특정 방향으로 광선을 쏴서 가장 먼저 닿은 Collider를 검사하는 기능이다.

- 이미지로 본다면, 대충 이런 느낌. 특정 Object에 있는 Collider를 확인한다. 이때, Raycast 는 가장 먼저 맞은 대상 하나를 검사하지만, RaycastAll 은 Ray에 맞은 여러 대상을 배열로 가져온다.
2. Tag와 Layer의 차이
① Tag
- 오브젝트의 정체성을 구분한다.
Player, Enemy, Boss, Item
- 주로, 이 오브젝트가 무엇인지를 분류하기 위한 용도로 사용한다.
② Layer

- 오브젝트의 물리/렌더링/검사 대상으로 어떻게 처리할지를 구분한다.
- Raycast 필터링, 충돌 제어, 카메라 렌더링 분리에 사용한다.
- Unity LayerMask는 Raycast에서 사용할 Layer 집합을 지정할 때 사용한다.
3. LayerMask
[SerializeField] private LayerMask targetLayer;
Physics.Raycast(transform.position, transform.forward, out hit, rayDistance, targetLayer)
- 위와 같은 방식으로 사용하는데, targetLayer 에 포함된 Layer의 Collider만 Raycast 검사 대상으로 삼아 사용한다.
① LayerMask의 번호를 지정할 때 유의할 점.
Physics.Raycast(origin, dir, out hit, distance, 9);
- 이때 숫자 9는 Layer 번호 9를 검사한다는 뜻이 아니다. 정수 9를 비트 마스크로 해석한다. Unity 공식 문서에서 이를 확인할 수 있다.
- 링크 : https://docs.unity3d.com/6000.3/Documentation/Manual/layermask-introduction.html

- 간단하게 해석하면, 숫자 9를 2진수로 해석하여 00001001로 인식한다. 이 경우, Layer 0과 Layer 3을 검사한다고 볼 수 있다.
4. 여러 대상 검사 ( RaycastAll, RaycastNonAlloc )
① RaycastAll
- Raycast는 가장 먼저 맞은 대상 하나만 검사하지만, RaycastAll은 Ray에 맞은 여러 대상을 배열로 가져온다.
② RaycastNonAlloc
- RaycastNonAlloc은 RaycastAll과 비슷하게 여러 대상을 검사하지만, 결과를 새 배열로 반환하지 않고 미리 만들어둔 배열에 저장한다.
- 이를 이용해서 반복적으로 호출되는 감지 로직에서는 GC 부담을 줄일 수 있다.
using UnityEngine;
public class RaycastAllExample : MonoBehaviour
{
[SerializeField] private float rayDistance = 10f;
[SerializeField] private LayerMask targetLayer;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
RaycastHit[] hits = Physics.RaycastAll(
transform.position,
transform.forward,
rayDistance,
targetLayer
);
foreach (RaycastHit hit in hits)
{
Debug.Log($"감지된 대상: {hit.collider.name}");
}
}
}
}
using UnityEngine;
public class RaycastNonAllocExample : MonoBehaviour
{
[SerializeField] private float rayDistance = 10f;
[SerializeField] private LayerMask targetLayer;
private RaycastHit[] hits = new RaycastHit[10];
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
int hitCount = Physics.RaycastNonAlloc(
transform.position,
transform.forward,
hits,
rayDistance,
targetLayer
);
for (int i = 0; i < hitCount; i++)
{
Debug.Log($"감지된 대상: {hits[i].collider.name}");
}
}
}
}
- 이처럼 RaycastAll은 Ray에 맞은 여러 대상을 배열로 반환한다. 사용은 쉽지만, 호출 시 배열 할당이 발생한다.
- RaycastNonAlloc은 미리 만들어둔 배열에 결과를 저장한다. 따라서, 반복 호출 시 GC 부담을 줄일 수 있다. 단, 배열 크기 만큼만 결과를 받아낸다.
5. Raycast의 활용 예시
① 총 발사
if (Physics.Raycast(cameraTransform.position,
cameraTransform.forward,
out hit,
shootDistance,
shootLayer))
{
if (hit.collider.TryGetComponent<Enemy>(out Enemy enemy))
{
enemy.TakeDamage(damage);
}
}
- FPS에서 총알을 실제 오브젝트로 날려서 충돌 판정을 보지 않고 처리할 수 있다.
- 카메라 쪽에서 Raycast를 쏴서 맞은 적에게 데미지를 주는 방식. 즉, 히트스캔 방식으로 구현할 수 있다.
② 상호 작용
// IInteractable.cs
public interface IInteractable
{
void Interact();
}
- 상호작용이라는 것이 가능한 객체에 대해서 IInteractable()을 구현할 수 있도록 별도의 인터페이스로 나눠준다.
// Door.cs
public class Door : MonoBehaviour, IInteractable
{
public void Interact()
{
// 문 열기/닫기
}
}
// ItemObject.cs
public class ItemObject : MonoBehaviour, IInteractable
{
[SerializeField] private string itemName = "체력포션";
public void Interact()
{
Destroy(gameObject);
}
}
- 이와 같이 Door와 ItemObject에 대해서 각자에게 맞는 Interact()을 구현한다.
if (Physics.Raycast(cameraTransform.position,
cameraTransform.forward,
out hit,
interactDistance,
interactLayer))
{
if (Input.GetKeyDown(KeyCode.E))
{
if (hit.collider.TryGetComponent<IInteractable>(out IInteractable interactable))
{
interactable.Interact();
}
}
}
- 이와 같은 방식으로 구현하면, PlayerInteraction은 대상이 무엇인지는 알지 않아도 된다. (문인지 아이템인지 몰라도 되고 그냥 해당 객체가 IInteractable()을 구현한 오브젝트인지만 확인하면 된다.)
'Unity > Unity 초격차캠프' 카테고리의 다른 글
| [20260527] Unity 정리 ( UI Canvas ) (0) | 2026.05.27 |
|---|---|
| [20260527] Unity 정리 ( Overlap 계열, Check 계열 ) (0) | 2026.05.27 |
| [20260526] Unity 정리 ( Raycast I ) (0) | 2026.05.26 |
| [20260526] Unity 정리 ( Prefab ) (0) | 2026.05.26 |
| [20260522] Unity 정리 ( Collider 충돌 처리 기초 - Collision, Trigger ) (0) | 2026.05.22 |