24.03.28 TIL Unity - 레이어 비트 연산을 통한 충돌 조건 검사

JJwoo·2024년 3월 28일
post-thumbnail

무언가와 충돌해서 상호 작용을 하는 메서드 등의 조건문 안에는 주로 부딪힌 오브젝트의 Tag 의 문자열을 검사하는 방식이 주로 쓰이고 있다.
나 역시 마찬가지였는데, 큰 프로젝트는 아니지만 문자열 검사보다 속도도 빠르고 성능적으로도 유리한 비트 연산을 이용해보려고 한다.

1. Tag의 문자열로 검사

익히 아는 그 녀석, 자세한 설명은 생략한다.



2. Layer의 숫자로 검사

속도 상으론 위의 Tag 문자열 검사보다는 빠르다.
하지만 레이어 비트 연산보다는 느리다.

p.s 레이어 번호 7,8,9 번은 현재 프로젝트에서 땅, 플랫폼, 몬스터 등에 사용하고 있는 중이라, 각자 검사 할 레이어 번호에 맞게 변경해서 대입하면 됩니다.



3. Layer 비트 연산으로 검사

성능 상으로 제일 빠르고 좋다.
일부 튜터님들이 좋아하신다.

조건문 안의 비트 연산 각 단계를 설명하자면 크게 세 가지이다.

  • 1 << collision.gameObject.layer : 충돌한 객체의 레이어를 비트 마스크로 변환

  • ((1 << 8) | (1 << 9)) : "Ground" 레이어와 "Platform" 레이어에 대한 비트 마스크를 결합
    (검사 레이어가 2개 이상인 경우)

  • != 0 : 비트 연산문을 Bool 타입으로 만들어 준다.
    이 부분이 없으면
    암시적으로 int 형식을 bool 형식으로 변환할 수 없다는 오류가 발생한다.
    < 오류 발생 이유 >
    C#에서는 조건문 안의 표현식이 bool 타입이어야 하는데
    비트 연산의 결과는 int 타입이기 때문에 '!= 0' 을 조건문에 추가하고 비트 연산의 결과가 0이 아닌지를 확인하여 bool 표현식을 만들어주어야 조건문 안에 쓸 수 있다.

왜 성능 차이가 날까?

연산 비용이 차이가 나는 이유는 각 연산의 복잡성과 메모리 접근(사용) 방식에서 기인한다.

  1. 비트 연산

    컴퓨터에서 가장 기본적이고 빠른 연산 중 하나.
    CPU에서 직접 처리되며, 매우 적은 연산 사이클을 요구함.
    비트 연산은 정수 연산을 기반으로 하므로, 추가적인 메모리 접근이나 복잡한 계산이 필요 없기에 효율적이며 빠르다.

  1. 레이어 숫자비교

    정수 비교 연산을 수행하기에 상대적으로 빠르지만 비트 연산보다는 약간 더 많은 처리 시간을 필요로 한다.
    비트 연산과 마찬가지로 이 방법도 CPU에서 직접 처리되며, 정수 비교는 비트 연산보다는 약간 더 많은 연산 사이클을 요구하기 때문에 비트 연산보다 느리다.

  1. 태그 문자열 비교

    문자열 비교는 위의 두 연산보다 훨씬 더 많은 연산 비용이 필요하다.
    문자열 비교는 각 문자를 차례대로 비교하는 과정도 있고, 문자열의 길이에 따라 비교하는 데 필요한 시간이 증가한다.
    또한, 문자열은 메모리 상에서 숫자보다 더 많은 공간을 차지한다.
    결과적으로 숫자 비교나 비트 연산에 비해 상대적으로 더 많은 시간과 메모리를 소모한다.

요약

비트 연산은 가장 기본적인 수준의 연산으로 다른 두 방식의 연산보다빠르다.
직접적인 체감은 크지 않지만, 성능이 정말 중요한 상황에서는 가능하다면 비트 연산을 사용하는 것이 좋을지도?

충돌한 오브젝트의 레이어 변경을 할 때도, NameTOLayer 방식 대신 레이어 숫자를 통해 변경해주어 코드의 가독성 + 성능을 잡을 수 있었다.

profile
개발 모코코

0개의 댓글