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 (뷰포트 좌표)
차이점 요약
활용 예