유니티에서 Physics2D.RayCast는 씬에 직선을 투영하여 대상에 적중하면 true를 리턴하는 물리함수이다. RayCast함수를 이용하면 충돌에 관련된 정보 또는 RayCast를 통한 다양한 로직을 구현할 수 있다.
RayCast 함수 사용법 (3D)
Ray를 생성하여 Ray가 발사되고, Ray에 충돌한 정보를 얻어와 저장하는것이 기본적인 방법이다.
void RayReturn()
{
Ray ray = new Ray(transform.position, transform.forward);
RaycastHit rayHitData;
Physics.Raycast(ray, out rayHitData);
}
Ray가 발사되고, Ray에 충돌한 정보를 rayHitData에 저장하게 된다.
위 Ray로 위치를잡고 발사하는것은 보통 3D에서 많이 쓰인다.
Raycast2D
3D와 2D의 차이는 알다시피 Z축이없다는 점이다. 그래서 Ray를 사용하지 않고, Vector2를 이용해서 Raycast가 출발할 좌표를 설정할 수 있다.
Physics2D.Raycast(Vector2 origin, Vector2 direction, float distance, int layerMask)
origin: Raycast가 출발할 좌표
direction: Raycast를 발사할 방향
distance: Raycast의 사거리
layerMast: Raycast가 감지할 레이어
etc
MinDepth는 지정한 Z좌표의 값보다 >= 크거나 같은 개체만 감지할수있게
MaxDepth는 지정한 Z좌표의 값보다 <= 작거나 같은 개체만 감지할수있게
이런식으로 나눌 수 있다.
Raycast의 경우 Ray가 처음으로 충돌하는 객체만을 감지하며, 다른 모든 충돌은 무시하게 되지만, Ray를 쏴 모든 충돌 객체의 정보를 리스트로 반환하여 여러개를 불러오고 싶을 때에는 RaycastAll을 사용한다.
RaycastAll
RaycastHit2D[] hits = Physics2D.RaycastAll(origin, direction);
foreach (RaycastHit2D hit in hits) {
// 각 충돌한 객체에 대한 처리
}
Raycast도 RaycastHit2D를 반환할 수 있지만, RayCastAll의 경우 Ray를 쏘는 선상의 모든 충돌체를 반환하다 보니 배열로 받게된다. 이를 foreach문을 이용해 충돌한 오브젝트에 대한 처리를 해줄 수 있다.
만약 일직선상의 모든것을 지우고싶다면 Vector2의 현재 오브젝트의 position을 찾아서 Ray로 정해주고 이를 원하는 거리만큼 쏴서 없애주면 된다.
그런데 일직선상에 모든것을 없애라고 해서 만약 없애기 싫은 충돌체와 없애고 싶은 충돌체가 겹쳐있다면 그 둘을 분간해줄수 있어야 하는데 이 때 필요한 것이 LayerMask 이다.
Tag와 같이 Layer를 지정해 줄 수 있다. 이는 inspector창에 있으며 객체들을 그룹화하고 그룹화된 정보로 다양한 기능을 제어할 수 있는 역할을 하는데 그 방법 중 하나이다.
Add Layer를 하여 자신이 원하는 Layer로 그룹화 한 후, 레이를 정해주고 위와같이 "Monster" 라는 Layer는 파괴하고 싶다고 정해주면 레이선상에서 Monster Layer를 가진 오브젝트들의 정보를 가져오고 필요한 로직을 짤 수 있다.
Vector2 rayOrigin = new Vector2(transform.position.x, transform.position.y); //현재 좌표
// x 축 양의 방향으로 레이 쏘기
RaycastHit2D[] hitsRight = Physics2D.RaycastAll(rayOrigin, Vector2.right, rayX, LayerMask.GetMask("Monster"));
foreach (var hit in hits)
{
// 현재 충돌한 게임오브젝트와 충돌한 게임오브젝트가 같지 않고, 충돌한 객체가 Monster 컴포넌트를 가지고 있을 경우 실행된다.
if (hit.collider.gameObject != gameObject && hit.collider.TryGetComponent(out Monster monsterComponent))
{
// 몬스터 비활성화.
monsterComponent.gameObject.SetActive(false);
GameManager.Instance.scoreManager.AddScore(monsterComponent.score);
}
}
이러면 내가정한 x축(코드상에서 rayX) 만큼 ray를 right방향으로 쏴서 LayerMask.GetMask()를 통해 Monster객체들을 SetActive(False) 하는 동작을 수행할 수 있다.
if문 내의 TryGetComponent 는 TryParse와 비슷한 느낌으로 true false를 반환하는 bool값인데,
TryGetComponent(out T component) 이며 특정 타입의 컴포넌트를 찾는데 사용되며 컴포넌트를 찾았을 경우 true 아니면 false를 반환한다.
'Unity' 카테고리의 다른 글
[유니티] 벽돌깨기 - 벽돌(몬스터) 풀링 (2) | 2023.12.07 |
---|---|
OnCollisionEnter2D, OnTriggerEnter2D 등등 (1) | 2023.12.05 |
[프로그래머스] 삼총사 C# (0) | 2023.12.01 |
[Unity] 벡터 및 계산 (0) | 2023.11.29 |
[Unity] GameManager 를 통해 Scene 아이디 주고받기 (TextMeshPro) (4) | 2023.11.28 |