내일배움캠프 TIL

내일배움캠프 58일차 TIL "타일맵 정보에 관련된 오류 수정"

Jooglorystar 2024. 12. 9. 21:16

 

 

본격적으로 여러 씬을 만들고, 그 씬간 이동 작업을 하면서 치명적인 버그가 있는 것을 발견하게 되었다.

 

 

 

위 이미지는 Farm Scene에서 경작, 파종, 물뿌리기 후 찍은 화면이다.

 

 

 

위 이미지는 실제 게임 플레이와 유사한 환경을 만들기 위해 Home Scene에 돌아온 뒤, 다음날 진행을 하고 찍은 사진이다.

 

 

그 다음 Farm 씬에 돌아와 확인한 결과, 지난 날에 물을 준 것도 남아있고, 전체적인 진행이 되지 않았다.

 

 

위 씬은 마을로 가기 위한 길목의 Scene이다. 위 Scene에 잠시 간 뒤에 다시 Home Scene으로 돌아가면

 

 

작업한 타일이 초기화되는 증상을 확인했다.

 

 

고쳐야하는 문제를 정리하면 다음과 같다.

 

1. 다음날 진행 시, 작물의 성장이 제대로 적용되지 않는 증상

2. 다른 씬에서 Farm 씬으로 돌아올 때, 경작, 물뿌리기 등의 작업이 제대로 적용되지 않는 증상

 

1. 다음날 진행 시, 작물의 성장이 제대로 적용되지 않는 증상

 위 증상의 원인은 작물을 성장하게 하는 메서드에 있었다.

public void UpdateGrowth()
{
    foreach (var (tilePosition, tileData) in GameManager.Instance.TilemapM.tileDataMap)
    {
        if (cropStateDictionary.TryGetValue(tilePosition, out CropState cropState))
        {
            if (tileData.IsWatered)
            {
                cropState.growingDate++;
                if (cropState.growingDate >= cropState.seedSO.growTime && cropState.growthStage < cropState.seedSO.maxGrowthStage)
                {
                    cropState.growthStage++;
                    UpdateCropSprite(tilePosition);
                    cropState.growingDate = 0;
                }
            }
            CheckDecayCrop(cropState);

        }
        SetCropSaveData(tilePosition, cropState);
    }

    SaveGameState();
}

 

작물을 성장하게 하는 메서드의 경우, 타일의 좌표와 타일의 데이터를 저장한 TilemapManager의 TileDataMap에서,

작물이 심어져 있는지와, 물이 주어졌는지, 정보를 판단하고 작물데이터 정보가 포함된 cropStateDictionary에서 작물이 심어진 좌표에서 작물 데이터를 변형하는 식으로 진행했었다.

 

TilemapManager는 Farm Scene의 타일맵 그리드에 컴포넌트로 존재했는데, 이 때문에 Home Scene에서 TileDataMap을 알 수가 없었던 것이었다.

 

해당 문제를 해결하기 위해서는 Home에서도 TileDataMap에 접근할 수 있어야한다는 결론을 내렸다.

 


이 문제는 다소 간단한 방식으로 해결했는데, Home Scene과 Farm Scene을 하나로 합쳤다.

 

 

HomeScene의 크기가 별로 크지 않았기 때문에, 이정도로 합치는 것은 크게 무리가 없을 것이라고 생각이 들었다.

실제로 해당 방법을 적용하니, FarmScene의 TileDataMap에 접근할 수 있어, 문제가 해결되었다.

 

 

2. 다른 씬에서 Farm 씬으로 돌아올 때, 경작, 물뿌리기 등의 작업이 제대로 적용되지 않는 증상

 

해당 증상도 어떤 의미에서는 1번 증상의 연장선이었다. FarmScene이 사라질 때, TileDataMap이 사라지고, 다시 불러오면서 문제가 생기는 것이었다.

만약 경작을 하거나, 물을 주는 등, 변화가 있으면, 해당 타일이 저장이 되지만, 만약 변화가 없었다면 해당 타일이 저장되지 않았기에, 저장하는 방식의 전환이 필요하다고 생각이 들었다.

 

우선, 팀원들과 이야기하여, 어디에서 농사를 지을 수 있는 지를 확인했다.

스타듀밸리나 목장이야기 같은 경우, 자신의 농장이 아니라도 농사를 지을 수 있다.

팀원들과의 논의 결과, 우리 게임은 우선 Farm Scene에서만 농사를 지을 수 있도록 한다고 하였다.

즉 여러 씬의 타일의 정보를 저장할 필요는 없었다.

 

 

이 문제의 해결을 위해, Farm 타일맵 그리드에 있던 TilemapManager를 씬이 지나도 파괴되지 않도록 하였다.

 

기본적으로 인게임에서 사용되는 씬과, 각 장소별 씬을 구분했는데, TilemapManager를 이 인게임의 씬으로 옮겼다.

 

그리고 FarmTilemap에 다음과 같은 스크립트를 붙였다.

 

using UnityEngine;
using UnityEngine.Tilemaps;

public class FarmTilemap : MonoBehaviour
{
    [SerializeField] private Tilemap _groundTilemap; // 땅 타일맵
    [SerializeField] private Tilemap _waterTilemap; // 물 타일맵
    [SerializeField] private Tilemap _cropTilemap; // 작물 타일맵

    private void Awake()
    {
        GameManager.Instance.TilemapM.GroundTilemap = _groundTilemap;
        GameManager.Instance.TilemapM.WaterTilemap = _waterTilemap;
        GameManager.Instance.TilemapM.CropTilemap = _cropTilemap;
    }

    private void OnEnable()
    {
        GameManager.Instance.TilemapM.UpdateTile();
    }
}

 

TilemapManager에서 사용할 타일맵을 이 타일맵으로 참조하고, 활성화시, 타일을 갱신하는 식으로 구성했다.

 

이로인해 TilemapManager는 씬 이동시에도 데이터가 파괴되지 않게 되었고, Farm 씬을 불러올 때마다 해당 정보가 잘 저장될 수 있었다.