유니티(Raycast & LayerMask)
Raycast
- 광선을 쏴서 충돌되는 물체가 있는지 검사
- 게임 속 물체를 클릭하는건 클릭한 화면의 위치로 부터 레이저를 쏴 닿은 물체가 있는지 확인하는것
- 하나의 물체가 닿으면 그 뒤에 물체는 관통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이고 비트 플래그로 사용됨
- 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);
- LayerMask와 Tag의 차이
- LayerMask
- int크기의 비트
- 32개까지만 가능
- 물리적인 처리에 대한 여부
- Tag
- 만들수있는 갯수 제한x
- 이름과 같이 문자열로서 그룹지음
Leave a comment