public LayerMask layerMask;
를 사용하여
if (Physics.Raycast(trnasform.position, out RaycastHit hitinfo, layerMask))
{
//~
}
Raycast로 광선을 쏴 Ground 체크를 최근에 굉장히 많이 사용했다. 지금도 사용하고있고... 그런데 이번에 코드를 작성하다 새로운 것을 배웠다. 바로 비트 연산을 사용해 레이어 포함 여부를 체크하는것.
int layerMask 1 << 6
if (Physics.Raycast(transform.position, out RaycastHit hitInfo, layerMask))
{
//~~
}
유니티에서 'Layer Mask'는 여러 레이어를 하나의 변수로 표현할수 있게 해주는 타입입니다. 각 레이어는 0부터 31까지 가능한 인덱스를 가지지요. 여기서 1 <<은 1 layer의 수 만큼 왼쪽 비트로 이동을 시키는 것입니다..
"<<"를 "비트 단위 이동"라 하는것이죠.
현재 내가 사용하는 레이어는 다음과 같다.

그리고 해당 레이어에 대응하는 비트만 1로 설정된 정수를 만드는것입니다.
현재 레이어를 0,1,2, 4,5,6,7을 사용하고있으므로

이러한 비트 연산을 사용하고있는것이지요. Layer3 인 네번째칸을 제외한 0부터 7까지 비트를 1로 만든것입니다.
이것이 바로 32비트 비트마스크에서 표현되는 방식입니다.
유니티에서 제가 만든 플레이어가 이동을할때 Rigidbody와 Capsule Collider를 사용하는데, 저는 계단 오르기 등의 감지를 위해 Floating Capsule이라는, 콜라이더를 플레이어의 머리를 기준으로 낮춰 땅에서 떨어트려놨습니다. 다리부분엔 Collider에 걸리지않도록요. 그래서 발 부분에는 Ground를 체크할 부분이 필요한데,
그라운드 체크를 위해 이렇게 작성했습니다.
using UnityEngine;
[System.Serializable]
public class PlayerLayerData
{
[field: SerializeField] public LayerMask GroundLayer { get; private set; }
public bool ContainsLayer(LayerMask layerMask, int layer)
{
return (1 << layer & layerMask) != 0;
}
public bool IsGroundLayer(int layer)
{
return ContainsLayer(GroundLayer, layer);
}
}
이 코드를 정리해보면.... public LayerMask GroundLayer;는 간단한 레이어 체크입니다. 쉽죠.
문제는 그 다음인데, ContainsLayer입니다.
1 << layer는 위에서 말한것처럼 비트를 이동시킨것입니다.
그리고 '&'를 사용했는데, "비트 AND 연산"을 사용해 만들어진 1 << layer값을 layerMask에 비교하게만들었습니다.



지면은 Environment라는 레이어고, 발이 닿고있는 네모난 부분은 GroundCheck입니다.
이러면 이제 1 << layer & layerMask != 0 의 힘이 발휘되는데, 이 레이어에 해당 레이어가 포함되어있으므로 AND 연산의 결과가 0이 아니게 될것입니다. 이를 염두에 두고, public bool IsGroundLayer(int layer)를 보겠습니다.
이 메서드를 활용해 주어진 레이어가 'GroundLayer'리는 LayerMask에 포함되어있는지 확인해 플레이어가 땅 위에 있는지 판별하였습니다.
public virtual void OnTriggerEnter(Collider collider)
{
if (stateMachine.Player.LayerData.IsGroundLayer(collider.gameObject.layer))
{
OnContactWithGround(collider);
return;
}
}
그래서 오직 포함된 그라운드일때만 Trigger가 발동하게 되어 점프 기능을 처리할떄 도움이 되었습니다.
'Unity Engine > Unity Common' 카테고리의 다른 글
| [Unity 3D] Mathf.Atan2() && Mathf.Rad2Deg (0) | 2023.11.04 |
|---|---|
| 캐릭터의 모델 높이 구하기 (0) | 2023.11.04 |
| 애니메이션 스테이트 체크 타이밍 (0) | 2023.10.20 |
| 유니티 쉐이더 컷씬 만들기 (0) | 2023.10.20 |
| 내일 할 것 :메기도 구현하기 (0) | 2023.10.19 |