2D RPG – 3. 이동불가 지역 설정

2D RPG 게임을 진행하다보면 NPC가 길을 막거나 벽이 길을 막는경우, 갈수없는 언덕 같은 지형이 있습니다.
이 같이 이동불가 지역을 만들어 보겠습니다.

1.Box Collider 추가

캐릭터 객체에 [Box Collider] 컴포넌트를 추가합니다.
이전의 입문 3D 캐릭터 애니메이션에서 캡슐 콜라이더의 2D 버전입니다.
충돌을 감지하는데 사용합니다.
[Edit Collider]를 선택하여 위치를 캐릭터의 발 위치로 지정해줍니다.

2.소스편집

변수선언 부분

    // BoxCollider 컴포넌트를 가져오기 위해 선언
    private BoxCollider2D boxCollider;

    // 통과불가능한 레이어를 설정해주기 위해 선언
    public LayerMask layerMask;

여기서 레이어라는 개념이 나옵니다.
안보이는 층을 생성하여 충돌을 체크하는데 쓰입니다.

start() 부분

        boxCollider = GetComponent<BoxCollider2D>();
        animator = GetComponent<Animator>();

애니메이터와 마찬가지로 [Box Collider] 컴포넌트도 가져옵니다.

코루틴 부분

            animator.SetFloat("DirX", vector.x);
            animator.SetFloat("DirY", vector.y);

            // A->B로 레이저를 쏴서 제대로 도착했을때 Null, 막혔을때 방해물이 Return
            RaycastHit2D hit;           

            // A지점, 캐릭터의 현재 위치값
            Vector2 start = transform.position;
            // B지점, 캐릭터가 이동하고자 하는 위치값 (시작지점+이동값)
            Vector2 end = start + new Vector2(vector.x * speed * walkCount, vector.y * speed * walkCount); 

            // 캐릭터에 BoxCollider가 적용되어 있어 그걸 충돌체로 인식하므로 해제 후 설정
            boxCollider.enabled = false;
            // 레이저 발사 (시작, 끝, 레이어마스크)
            hit = Physics2D.Linecast(start, end, layerMask);
            boxCollider.enabled = true;          

            // 벽으로 막혔을때 실행하지 않게 처리
            if (hit.transform != null)
            {
                break;
            }


            animator.SetBool("Walking", true);

x와 y값을 받아온 뒤에 충돌 체크를 합니다.
[layerMask]는 추후 레이어 생성으로 할당됩니다.

3.레이어 설정

유니티로 돌아와서 새로운 레이어를 하나 추가합니다.
추가한 레이어를 스크립트 파일 변수에 [Layer Mask]로 지정합니다.
이 의미는 레이저를 쏠 때 부딪히는 레이어를 의미합니다.

이제 벽으로 사용할 게임오브젝트를 추가하고 크기를 지정해주고 레이어를 앞서 추가한 레이어로 설정해줍니다.

모든 설정은 끝났습니다.
원리는 캐릭터 객체에서 레이저를 레이어로 발사하여 막혀있을시 정지하고, 아닐시 실행하는 원리입니다.

4.캐릭터 객체의 중심이동

위에서 말하는 레이저는 객체의 중심에서 시작됩니다.
저희는 [Box Collider]를 캐릭터의 발부분에만 설정했기 때문에 캐릭터 객체의 중심도 이동이 필요합니다.
이를 위해서는 이전에 슬라이스 했던 이미지의 [Sprite Editor]가 다시 필요합니다.

0.5는 캐릭터 가로의 50%부분, 0.2는 하단에서 20%부분을 의미합니다.
실행해보면 캐릭터가 벽에 막히면 이동하지 않는것을 확인할 수 있습니다.