코린이 부트캠프 일상

유니티 타일맵 오류 해결하기

게발인개발자 2024. 2. 7. 09:02

지금 만들고 있는 게임에서 타일맵을 플레이어가 부수거나 설치할 수 있게 해주는 시스템을 만들었는데

오류가 생겨서 오류에 대해 정리하려고 한다.

 

일정 방향에서 벽을 공격했을 때 벽에 대한 정보를 가지고 올 수 없는 오류

일정 방향에서 벽을 공격 했을 때 벽에 대한 정보를 가지고 올 수 없는 오류인데

 

public void Start()
{
    // Bounds는 구조체
    // 해당 Tile의 크기만큼 싹 for문을 돌린다. tile이 있으면 Dictionary에 추가. 각각 TileInfo의 값을 받는다.
    BoundsInt bounds = tilemap.cellBounds;
    for (int x = bounds.x; x < bounds.x + bounds.size.x; x++)
    {
        for (int y = bounds.y; y < bounds.y + bounds.size.y; y++)
        {
            Vector3Int cellPosition = new(x, y, 0);
            TileBase tile = tilemap.GetTile(cellPosition);  
            
            if (tile != null)
            {
                float tileHP = GetTileHp(cellPosition);
                float tileMinDamage = GetTileMinDamage(cellPosition);
                wallDictionary[cellPosition] = new TileInfo
                {
                    tile = tile,
                    HP = tileHP,
                    minMiningAttack = tileMinDamage
                };
            }
        }
    }
}

게임이 시작되면 맵 타일맵 중 wall 타일에 있는 모든 타일을 해당 위치 값에 딕셔너리로 저장하여 벽의 정보에 접촉할 수 있게 해주었다.

 

private void PlayerMining()
{
    Vector2 mousePosition = mainCamera.ScreenToWorldPoint(Input.mousePosition);
    Vector2 direction = (Vector3)mousePosition - gameObject.transform.position;
    RaycastHit2D hit = Physics2D.Raycast(transform.position, direction, 1.5f, 1 << 6);
    if (hit)
    {
        Vector3Int cellPosition = TilemapManager.instance.tilemap.WorldToCell(hit.point);
        if (cellPosition == null)
        {
            return;
        }
        else
        {
            if (TilemapManager.instance.wallDictionary[cellPosition].minMiningAttack < statsHandler.CurrentStats.miningAttack)
            {


                if (TilemapManager.instance.wallDictionary[cellPosition].HP > 0f)
                {
                    TilemapManager.instance.wallDictionary[cellPosition].HP -= statsHandler.CurrentStats.miningAttack;
                    Debug.Log(TilemapManager.instance.wallDictionary[cellPosition].HP);

                    // 벽이 부서졌다면
                    if (TilemapManager.instance.wallDictionary[cellPosition].HP <= 0f)
                    {
                        TilemapManager.instance.tilemap.SetTile(TilemapManager.instance.tilemap.WorldToCell(cellPosition), null);
                        ItemManager.instance.itemPool.ItemSpawn(2101, cellPosition);
                        // 타일의 지붕 없애기.
                        Vector3Int ceilingPosition = new Vector3Int(cellPosition.x, cellPosition.y + 1, 0);
                        if (TilemapManager.instance.ceilingTile.GetTile(ceilingPosition))
                        {
                            TilemapManager.instance.ceilingTile.SetTile(ceilingPosition, null);
                        }
                    }
                }
            }
            else
                return;
        }
    }
}

벽을 부술 때는 레이캐스트로 해당 벽의 위치를 가지고 와서 부술 수 있게 해주었다. 근데 여기서 문제가

 

벽의 저장할 때에는 boundsint로 x,y 값의 최솟값으로 위치를 저정하지만

벽을 오른쪽이나 위에서 부술 때는 버림값으로 x,y 값을 가지고 왔는데

(0,0)이 아닌 (0,1) / (1,0)/ (1,1) 정보를 가지고 올려고 해서 null 오류가 났다 

그래서 해결하기위해 예외처리와 해당 상황에서 특정 조건문을 통해 해결할려고 하고 있다