육각형 그리드 간격 조절하기

정선호·2023년 8월 8일
0

Original

목록 보기
1/5
post-thumbnail

전략 게임이나 빌드 시뮬레이션 게임 같은 곳에서 물건을 배치할 때 주로 그리드를 사용하는데
그리드에서 일정한 간격으로 무언가를 배치하게 하는 것을 간단한 스크립트로 구현해 보고 싶었다.

사각형 그리드

사각형 그리드에 간격을 주는 것은 가장 간단하다.

x와 y좌표가 명확히 눈에 보이고 특정 x와 y에만 true가 오게 스크립트를 작성해주면 된다.

아이소메트릭 그리드

아이소메트릭 그리드 또한 사각형 그리드와 크게 다를 것이 없다.
단지 원점의 위치와 퍼져나가는 방향이 다르고, 사각형이 찌그러져 있을 뿐이다.

상황에 따라 다르겠지만, 원점과 퍼지는 방향만 알고 있으면 알기 쉽다.

육각형 그리드

이 글을 작성하게 된 계기이다.
육각형은 사각형과 다르게 지그재그로 셀이 배치되어 있기 때문에 좌표계로 접근하던 사각형 계열 그리드와는 다른 접근방식이 필요하다.
위의 사진은 유니티에서 제공하는 Top Point HexGrid이다.
층마다 y좌표가 1 증가하고, 칸마다 x좌표가 1 증가한다.

이 헥스맵에서 (0,0,0)셀을 기준으로 모든 셀이 한 칸씩 떨어져 있게끔 그리드를 잡아주고 싶을 때 어떻게 해야할까

언뜻 보기에는 감이 잘 잡히지 않는다. 점간의 규칙을 찾기란 쉽지 않기 때문이다.
하지만 이렇게 선을 그어보면 금방 감이 잡힐 것이다.

저 하늘색 점은 빨간색 가로선과 대각선들의 접점인 것이다. 따라서 가로선과 세로선을 둘 다 만족하는 점을 찾으면 된다.

(0, 0)을 기준으로 모든 셀이 n칸씩 떨어져 있게끔 오브젝트를 설치할 수 있을 때, 설치 여부를 확인하고 싶은 좌표가 (x, y)라 할 때 각각 x와 y에 대해 다음을 체크하면 된다.

  • y % (n + 1) == 0
  • (x + y / 2) % (n + 1) == 0

이를 스크립트로 구현하면 다음과 같다.

private bool CheckAvailablePoint(Vector3Int pos)
{
    if (interval != 0)
    {
        int inter = interval + 1;
            
        int halfY = pos.y >= 0 ? (pos.y + 1) / 2 : (pos.y - 1) / 2;
        int abX = pos.y >= 0 ? pos.x + halfY : pos.x - halfY;
            
        if (pos.y % inter != 0)
        { 
             return false;
        }

        if (abX % inter != 0)
        { 
             return false;
        }
    }

    return true;
}

결과

profile
학습한 내용을 빠르게 다시 찾기 위한 저장소

0개의 댓글