Ray 생성 : Ray 클래스는 시작 위치와 방향을 정의하여 Ray를 만듭니다.
예를 들어, Ray ray = new Ray(transform.position, transform.forward);는 현재 오브젝트 위치에서 정면 방향으로 Ray를 생성합니다.
Raycast : Physics.Raycast 함수를 사용해 Ray가 다른 Collider와 충돌하는지를 검사합니다.
예를 들어, Physics.Raycast(ray, out RaycastHit hitInfo, maxDistance)와 같이 사용하면 지정한 거리 내에서 Ray와 충돌한 첫 번째 오브젝트에 대한 정보를 얻을 수 있습니다.
RaycastHit : Raycast가 충돌한 오브젝트의 정보를 포함합니다. hitInfo.collider를 통해 충돌한 오브젝트의 Collider에 접근할 수 있습니다.
using UnityEngine;
public class RayExample : MonoBehaviour
{
void Update()
{
// 카메라에서 마우스 위치로 향하는 Ray 생성
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// RaycastHit에 충돌 정보 저장
RaycastHit hitInfo;
// Raycast를 사용하여 충돌 감지
if (Physics.Raycast(ray, out hitInfo, 100f)) // 100f는 Ray의 최대 거리
{
Debug.Log("충돌한 오브젝트: " + hitInfo.collider.name);
}
}
}
int layerMask = LayerMask.GetMask("Enemy");
if (Physics.Raycast(ray, out hitInfo, 100f, layerMask))
{
Debug.Log("Enemy 레이어 오브젝트와 충돌!");
}
활용예시
- FPS 게임에서 총알 경로 설정 : Ray를 통해 총알의 궤적을 계산하고, 충돌 지점에 파티클 효과를 생성할 수 있습니다.
- RTS 게임에서 유닛 선택 : 마우스 클릭으로 Raycast를 발사하여 유닛을 선택하거나 명령을 내릴 수 있습니다.
- 플랫폼 게임에서 시야 판별 : 캐릭터 시야 안에 특정 오브젝트가 있는지 확인할 수 있습니다.
Ray : 직선의 시작점(origin)과 방향(direction)Ray ray = new Ray(transform.position, transform.forward); : 오브젝트Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0)); : 카메라 중심Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); : 마우스Ray ray = new Ray(Vector3 origin, Vector3 direction);origin : Ray가 시작하는 위치, Vector3 타입이며, 보통 월드 좌표계를 기준으로 지정direction : Ray가 향하는 방향, Vector3 타입Vector3 startPoint = new Vector3(0, 1, 0); // 시작 위치
Vector3 direction = Vector3.up; // 위쪽 방향
Ray ray = new Ray(startPoint, direction);
// Ray는 (0, 1, 0) 지점에서 시작하여 위쪽(Vector3.up, 즉 (0, 1, 0))으로 뻗어나감Vector3 viewportPoint : 2D 화면의 Viewport 좌표. using UnityEngine;
public class Example : MonoBehaviour
{
void Update()
{
// 마우스 위치를 Viewport 좌표로 변환
Vector3 viewportPoint = Camera.main.ScreenToViewportPoint(Input.mousePosition);
// Viewport 좌표를 기준으로 광선을 생성
Ray ray = Camera.main.ViewportPointToRay(viewportPoint);
// 광선이 맞는 객체가 있는지 확인
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
Debug.Log("Hit object: " + hit.collider.name);
}
}
}
- ScreenToViewportPoint : 마우스의 화면 좌표를 Viewport 좌표로 변환합니다.
- ViewportPointToRay : 변환된 Viewport 좌표에서 카메라를 향해 광선을 쏩니다.
- Physics.Raycast : 생성된 광선이 무엇인가와 충돌하는지 확인합니다.
Ray ray = Camera.main.ScreenPointToRay(screenPosition);screenPosition : Vector3 타입으로, 화면의 좌표를 의미.Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);using UnityEngine;
public class RaycastExample : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown(0)) // 마우스 왼쪽 버튼 클릭 시
{
// 마우스 위치로부터 Ray 생성
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
// Raycast를 사용해 충돌 감지
if (Physics.Raycast(ray, out hitInfo))
{
Debug.Log("충돌한 오브젝트: " + hitInfo.collider.name);
}
}
}
}bool hit = Physics.Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask, QueryTriggerInteraction queryTriggerInteraction);
매개변수
origin (필수) : Ray의 시작 위치 (Vector3). 예를 들어, 캐릭터나 카메라의 위치에서 시작할 수 있습니다.direction (필수) : Ray가 향하는 방향 (Vector3). 예를 들어, 앞쪽을 향하는 transform.forward 벡터 등을 사용할 수 있습니다.hitInfo (선택) : 충돌된 오브젝트에 대한 정보를 담는 RaycastHit 구조체입니다. out 키워드를 사용하여 값을 전달받으며, 충돌 지점의 좌표, 충돌한 오브젝트의 콜라이더 등의 정보를 포함합니다.maxDistance (선택) : Ray의 최대 거리 (float). Ray가 이 거리를 넘어가면 충돌하지 않은 것으로 간주됩니다.layerMask (선택) : 특정 레이어에 속한 오브젝트만 충돌 대상으로 지정하는 레이어 마스크(int). 레이어 마스크를 사용하면 Ray가 특정 레이어에 속한 오브젝트에만 반응하도록 할 수 있습니다.queryTriggerInteraction (선택) : 트리거 콜라이더와의 충돌 여부를 설정하는 QueryTriggerInteraction 열거형입니다. 기본값은 QueryTriggerInteraction.UseGlobal로, 물리 설정에 따라 트리거와 충돌할지 결정됩니다.반환값
bool 타입으로, 충돌이 발생하면 true, 발생하지 않으면 false를 반환합니다.예시
기본적인 Raycast 사용
origin과 direction을 지정하여 Ray를 발사하고, 충돌한 오브젝트가 있는지 검사하는 간단한 예제입니다.
void Update()
{
Vector3 origin = transform.position; // Ray 시작 위치
Vector3 direction = transform.forward; // Ray 방향
if (Physics.Raycast(origin, direction, out RaycastHit hitInfo))
{
Debug.Log("충돌한 오브젝트: " + hitInfo.collider.name);
}
}
거리를 지정하여 Raycast 사용
maxDistance를 설정하여 지정된 거리 내에서만 충돌을 감지할 수 있습니다
float maxDistance = 10f;
if (Physics.Raycast(origin, direction, out RaycastHit hitInfo, maxDistance))
{
Debug.Log("충돌한 오브젝트: " + hitInfo.collider.name);
}
레이어 마스크를 사용하여 특정 레이어만 감지
layerMask를 사용하면 특정 레이어에만 Ray를 감지하도록 할 수 있습니다.
int layerMask = LayerMask.GetMask("Enemy");
if (Physics.Raycast(origin, direction, out RaycastHit hitInfo, maxDistance, layerMask))
{
Debug.Log("Enemy 레이어에 속한 오브젝트와 충돌!");
}
트리거 콜라이더와의 충돌 설정
QueryTriggerInteraction을 사용하여 트리거 콜라이더와의 충돌 여부를 결정할 수 있습니다.
if (Physics.Raycast(origin, direction, out RaycastHit hitInfo, maxDistance, layerMask, QueryTriggerInteraction.Collide))
{
Debug.Log("트리거 콜라이더와도 충돌 감지");
}
RaycastHit 구조체는 Ray가 충돌한 위치에 대한 상세 정보를 제공합니다. 주요 속성으로는 다음이 있습니다
collider (Collider) : 충돌한 오브젝트의 콜라이더. point (Vector3) : Ray가 충돌한 월드 좌표.normal (Vector3) : 충돌한 표면의 법선 벡터. distance (float) : Ray의 시작점에서 충돌 지점까지의 거리.transform (Transform) : 충돌한 오브젝트의 Transform을 반환.rigidbody (Rigidbody) : 충돌한 오브젝트에 연결된 Rigidbody 컴포넌트를 반환.textureCoord (Vector2) : 충돌 지점의 텍스처 좌표(UV 좌표)를 반환lightmapCoord (Vector2) : 충돌 지점의 라이트맵 UV 좌표를 반환using UnityEngine;
public class RaycastExample : MonoBehaviour
{
public ParticleSystem hitEffect;
void Update()
{
if (Input.GetMouseButtonDown(0)) // 마우스 왼쪽 버튼 클릭 시
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hitInfo, 100f))
{
// 충돌 지점에 파티클 생성
Instantiate(hitEffect, hitInfo.point, Quaternion.LookRotation(hitInfo.normal));
// 충돌 정보 출력
Debug.Log("충돌한 오브젝트 이름: " + hitInfo.collider.name);
Debug.Log("충돌 지점까지의 거리: " + hitInfo.distance);
}
}
}
}
둘 다 Unity에서 화면상의 점을 3D 공간의 광선(Ray)으로 변환할 때 사용되는 함수이지만, 화면 좌표계의 기준이 다르다는 점에서 차이가 있습니다.
ScreenPointToRay
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);ViewportPointToRay
Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));요약
Screen과 Viewport
모두 화면의 좌표를 나타내지만, 기준이 서로 다릅니다.
Screen (스크린 좌표)
Viewport (뷰포트 좌표)
차이점 요약
활용 예