• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

강의 22:00분 쉬프트 연산자 질문

21.12.03 22:44 작성 조회수 223

0

(저는 일단 쉬프트연산자가 a << b라고하면 a를 b만큼 왼쪽으로 옮긴다 정도만 알고있습니다)

int _mask = (1 << (int)Define.Layer.Ground | (1 << (int)Define.Layer.Monster);

부분에서 

Define에 있는 Ground는 현재 값을 9, Monster = 8로 해두었는데

1. 왜 _mask의 값을 쉬프트 연산자로 1을 왼쪽으로 9만큼(Define.Layer.Ground)옮기고 Monster일때는 1을 왼쪽으로 8만큼 옮기게 해서 _mask에 값을 할당을 하나요?

2. _mask에 왜 하드코딩으로 값을 넣어주지 않고 쉬프트 연산자를 사용해서 정수값을 넣어주나요??

3. 1 << (int)Define.Layer.Ground하게 되었을때 1을 왼쪽으로 9칸 보내면 0001 0000 0000 으로(2진수) 256이 되서? AddLayer의 9번과 안 맞는것 아닌가요...???

4. 쉬프트연산을 사용하는것이 빠르다면 왜 빠른것인가요??

답변 1

답변을 작성해보세요.

0

안녕하세요,

우선 이해안가시는 모든 부분에 대해 일일히 답변을 드릴 수는 없기 때문에
구글링을 열심히 하시고, 그래도 이해가 안가는게 있을 때만 질문을 하셔야 합니다.
질문주신 부분에서 구글에 검색할 키워드는 [비트마스크]이고 은근히 중요한 주제입니다.
우선 구글링을 통해 충분히 이해가 되었다는 가정하에, 답변을 드리면 다음과 같습니다.

1. 왜 _mask의 값을 쉬프트 연산자로 1을 왼쪽으로 9만큼(Define.Layer.Ground)옮기고 Monster일때는 1을 왼쪽으로 8만큼 옮기게 해서 _mask에 값을 할당을 하나요?

비트마스크이기 때문입니다. 어떤 숫자 value랑 _mask랑 AND를 하게 되면,
깨알같이 필요한 데이터만 추출됩니다.

value :
 

mask : 

value & mask로 and 하면 value에서 8, 9 비트 값만 남기고 나머지는 다 0으로 날아감

2. _mask에 왜 하드코딩으로 값을 넣어주지 않고 쉬프트 연산자를 사용해서 정수값을 넣어주나요??

그냥 넣어도 됩니다.
단지 1 << 형식으로 넣어야 마스크를 만들어준다는게 더 이해하기 쉬울 뿐이죠.

3. 1 << (int)Define.Layer.Ground하게 되었을때 1을 왼쪽으로 9칸 보내면 0001 0000 0000 으로(2진수) 256이 되서? AddLayer의 9번과 안 맞는것 아닌가요...???

음~ 질문이 잘 이해가 안갑니다. AddLayer의 9번과 안 맞는다는게 어떤 의미일까요?

4. 쉬프트연산을 사용하는것이 빠르다면 왜 빠른것인가요??

CPU에서 제공하는 가장 쉽고 단순한 명령어이기 때문입니다.
그리고 데이터 저장 방식도 훨씬 효율적으로 int 하나에 32개의 경우의 수를 담아넣을 수 있습니다.


starkshn님의 프로필

starkshn

질문자

2021.12.05

제가 질문드린 1번과 1번의 답변은 구글링을 통해 이해가 갔습니다.

그래서 지금 _mask에 1 << (int)Define.Layer.Ground | (int)Define.Layer.Monster 이렇게 Ground 레이어와 Monster 레이러를 or 연산자로 int _mask에 할당하셨는데

1. int형에 어떻게 두가지의 정수값을 넣을 수 있는 것인가요?

 

2. 여기서 두가지의 정수를 _mask에 할당을 받았기 때문에 밑에

int _mask = (1 << (int)Define.Layer.Ground | (1 << (int)Define.Layer.Monster));

    

 

    void OnMouseClicked(Define.MouseEvent evt)

    {

        if (_state == PlayerState.Die)

            return;

 

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        //Debug.DrawR  ay(Camera.main.transform.position, ray.direction * 100.0f, Color.red, 1.0f);

        

        RaycastHit hit;

 

        if (Physics.Raycast(ray, out hit, 100.0f, _mask ) )

        {

            _destPos = hit.point;

            _state = PlayerState.Moving;

 

            if (hit.collider.gameObject.layer == (int)Define.Layer.Monster)

            {

                Debug.Log("Monster Clicked!");

                Debug.Log(_mask);

            }

            else

            {

                Debug.Log("Ground Clicked!");

                Debug.Log(_mask);

            }

           

이 코드에서 hit.collider.gameObject.layer == Ground일때와 Monster일때로 구분 할 수 있는것 인가요?

 

1. 
두개의 정수를 넣은 것이 아니구요.
(int)Define.Layer.Ground | (int)Define.Layer.Monster 
여기서 | 은 bitwise OR 연산입니다.

이런 식으로 1 <<8과 1<<9가 합쳐지게 됩니다.
결과적으로 768이라는 숫자를 넣은 것과 동일합니다.

2.
Physics.Raycast 내부적으로 특정 물체의 Layer를 확인해서,
해당 Layer가 우리가 Bitmask로 켜둔 것인지를 확인하겠죠.
가령 Layer가 Monster (8)인 오브젝트가 있는데,
우리가 8번과 9번은 1으로 설정한 Bitmask를 넘겨줬으니
충돌이 인정되고 이런식입니다.

starkshn님의 프로필

starkshn

질문자

2021.12.05

1. 768인것은 이해를 했습니다.

 

2. 우리가 쉬프트 연산자로 1 << 8, 1<< 9를 해주어서,  쉬프트 연산자로 768을 _mask에 넣어주었는데

 질문1. 그렇다면 _mask는 BitMask전용? 정수값인건가요?

질문2. _mask의 Bitmask 9번과 8번을 켜주었으니(1로 On/Off)

Physics.Raycast의 마지막인자에 _mask를 넣어주었으니 ,

8번Layer인 몬스터를 클릭을 했을때,

컴퓨터가 _mask의 비트마스크 8번째 자리숫자를(사람이 보았을때는 10진수로  128)인 값에 1이 켜져있으니까 충돌 판정을 내리는 원리 인것인가요?

1) 네 그렇습니다.
2) 네 그렇습니다. 내부 구현이 그렇게 되어 있겠죠.
직접 bitmask 판별 코드를 구현했다면
(1 << 8) & _mask를 해본 다음 이게 0이 아닌지를 보면 됩니다.

starkshn님의 프로필

starkshn

질문자

2021.12.06

제가 마음이 급해서 구글링 하다가도 사소한거 질문을 자주 많이 하는데 친절하게 항상 답변해주셔서 감사합니다 덕분에 조금이나마 이해가 되었습니다.