728x90
반응형

ChronoWave를 스마일게이트멤버십에 제출하고 남는 시간동안 진행할 프로젝트를 위한 Hexagon TileMap 만들기

https://www.youtube.com/watch?v=rjBD-4gNcfA 

https://www.youtube.com/watch?v=BE54igXh5-Q 

 

Hexagon Model

여러가지 방법이 있겠지만 계산하기 귀찮으니 3D Model을 사용하자

먼저 Blender로 간단하게 육각형을 만들어준다.

더보기

일단 있는 거 싹 지우고 Circle을 추가

 

Circle의 Vertices를 6으로 변경

 

 

Edit 모드로 변경

 

F를 눌러 Face 채우기

 

Extrude Region 선택해서 대충 두께올리기

계산하기 편하기 1로 올려놨다.

 

저장하고 Unity에서 불러온다.

Unity에서 두께(Z Scale)을 0.02로 조정했다.
이후 Prefab으로 만들어준다.

 

TileMap Generator

Hierachy에 TileGenerator라는 이름의 빈 오브젝트를 만들고 HexTileMapGenerator.cs를 추가한다.
Hierachy가 너무 지저분해지지 않게 TileMapHolder도 만들어준다.

using UnityEngine;

public class HexTileMapGenerator : MonoBehaviour
{
    public GameObject hexTilePrefab;
    public Transform tileMapHolder;

    [SerializeField] private int mapWidth = 25;
    [SerializeField] private int mapHeight = 12;
    [SerializeField] private int mapRadius = 20;

    private float tileXOffset = 1.75f;
    private float tileZOffset = 1.5155444566227676318365155488176f;

    void Start()
    {
        CreateHexTileMap();
    }

    void Update()
    {

    }

    private void CreateHexTileMap()
    {
        for(float x = 0; x < mapWidth; x++)
        {
            for(float z = 0; z < mapHeight; z++)
            {
                GameObject tempGO = Instantiate(hexTilePrefab);

                if(z % 2 == 0)
                {
                    tempGO.transform.position = new Vector3(x * tileXOffset, 0, z * tileZOffset);
                }
                else
                {
                    tempGO.transform.position = new Vector3(x * tileXOffset + tileXOffset/2, 0, z * tileZOffset);
                }
                SetTileInfo(tempGO, x, z);
            }
        }
    }

    private void SetTileInfo(GameObject go, float x, float z)
    {
        go.transform.parent = tileMapHolder;
        go.name = "(" + x.ToString() + ", " + z.ToString() + ")"; 
    }
}

 

실행하면 이렇게 hexagon Tile들이 생성된다.

 

원형 Hexagon TileMap

그냥 사각형은 재미가 없으니까 원형으로 해주자.

간단하게 반경에 있으면 생성하고 아니면 안하는 식으로 하면 된다.

using UnityEngine;

public class HexTileMapGenerator : MonoBehaviour
{
    public GameObject hexTilePrefab;
    public Transform tileMapHolder;

    [SerializeField] private int mapWidth = 25;
    [SerializeField] private int mapHeight = 12;
    [SerializeField] private int mapRadius = 20;

    private float tileXOffset = 1.75f;
    private float tileZOffset = 1.5155444566227676318365155488176f;

    void Start()
    {
        CreateHexTileMap();
    }

    void Update()
    {

    }

    private void CreateHexTileMap()
    {
        float mapXMin = -mapWidth / 2;
        float mapXMax = mapWidth / 2;

        float mapZMin = -mapHeight / 2;
        float mapZMax = mapHeight / 2;

        for(float x = mapXMin; x < mapXMax; x++)
        {
            for(float z = mapZMin; z < mapZMax; z++)
            {
                GameObject tempGO = Instantiate(hexTilePrefab);

                if(z % 2 == 0)
                {
                    tempGO.transform.position = new Vector3(x * tileXOffset, 0, z * tileZOffset);
                }
                else
                {
                    tempGO.transform.position = new Vector3(x * tileXOffset + tileXOffset/2, 0, z * tileZOffset);
                }

                if(Vector3.Distance(transform.position, tempGO.transform.position) <= mapRadius)
                {
                    SetTileInfo(tempGO, x, z);
                }
                else
                {
                    Destroy(tempGO);
                }
            }
        }
    }

    private void SetTileInfo(GameObject go, float x, float z)
    {
        go.transform.parent = tileMapHolder;
        go.name = "(" + x.ToString() + ", " + z.ToString() + ")"; 
    }
}

 

Radius를 10으로 설정하면 아래와 같이 나온다.