작업내용
타일 브러시
- 기능 추가: Ctl+Click 으로 직선 그리기
- 위치 및 테스트 아이콘 추가)
맵 저장/불러오기
- 타일 맵 저장, 다른이름으로 저장 GUI 와이어 프레임
- 타일 맵의 이름 설정 후 Json 형식으로 로컬폴더에 저장
- 불러오기
직선 그리기 코드
점이 이동하며 그리는 직선은 타일맵 위를 지나며 좌표계에서 중심각이 45도를 넘지 않는다.
이때 점이 X축 기준으로 한 타일의 거리만큼 이동할 때, 두 개의 타일을 지나는 경우를 탐색했다.
(더 좋은 탐색 방법이나 빼먹은 경우의 수가 있다면 조언 부탁드립니다!)
코드
더보기
// BrushButtonsWidget
/// <summary>
/// 시작점에서 끝점까지 그린 직선에 걸리는 타일의 타입을 선택된 브러시 타입으로 변경.
/// </summary>
public bool DrawTilesThose(TileComponent currentTileComponent)
{
if (selectedBrush == null) return false;
TileMapComponent tileMapComponent = PuzzleManager.instance.tileMapComponent;
TileComponent oldSelectedTileComponent = tileMapComponent.currentSelectedTile.GetComponent<TileComponent>();
List<List<GameObject>> tileList = tileMapComponent.tileList;
Vector2Int startIndexes = oldSelectedTileComponent.currentTilePosition;
Vector2Int endIndexes = currentTileComponent.currentTilePosition;
Vector2Int distance = new Vector2Int(
Mathf.Abs(endIndexes.x - startIndexes.x)+1,
Mathf.Abs(endIndexes.y - startIndexes.y)+1
);
// 시작점과 끝점의 선을 대각선으로 하는 사각형이 가로형인지 세로형인지 구분해 사용.
// 탐색은 가로형에 맞춰 진행되며, Tangent 값의 범위는 0~1 사이.
bool isWide = distance.x >= distance.y;
int countOfLoop = isWide ? distance.x : distance.y;
float tangent = isWide ?
Mathf.Floor(100.0f * distance.y / distance.x) * 0.01f :
Mathf.Floor(100.0f * distance.x / distance.y) * 0.01f;
float stackedTangent = 0;
float limitTangent = 1;
int index_H = 0;
int index_V = 0;
int dir_h = startIndexes.x > endIndexes.x ? -1 : 1;
int dir_v = startIndexes.y > endIndexes.y ? -1 : 1;
int startX = startIndexes.x;
int startY = startIndexes.y;
// 2차 배열 타일맵의 탐색이지만, 반복문은 한 번만 사용된다.
for (int i = 0; i < countOfLoop; i++)
{
int indexX = startX + ((isWide ? i : index_H) * dir_h);
int indexY = startY + ((isWide ? index_V : i) * dir_v);
if (isWide && tangent == 1)
{
// 시작점과 끝점의 선분 각도가 45도 인 경우 X=Y.
DrawTileThat(tileList[indexX][indexY].GetComponent<TileComponent>());
index_V += 1;
}
else
{
// 일반적으로 시작점과 끝점의 선분이 하나의 타일을 지나는 경우.
stackedTangent += tangent;
DrawTileThat(tileList[indexX][indexY].GetComponent<TileComponent>());
// 시작점과 끝점의 선분이 두 개 이상의 타일을 지나는 경우.
if (Mathf.Floor(stackedTangent) == limitTangent)
{
if (isWide) index_V += 1;
if (!isWide) index_H += 1;
if (stackedTangent != limitTangent)
{
DrawTileThat(tileList[indexX][indexY].GetComponent<TileComponent>());
}
stackedTangent = 0;
}
}
}
return true;
}
저장 / 불러오기
과거 엔진의 JsonUtility 내장 함수를 사용했었는데, 애셋 스토어를 들렀다가 멋진(Free!) 플러그인을 발견했다.
JSON .Net for Unity 플러그인이다. 덕분에 손쉬운 직렬화!
그리고 파일의 저장/불러오기에 사용할 브라우저 플러그인도 발견했다! 역시 멋졌다(Free!).
이름하야 Runtime file browser.
저장, 불러오기 테스트 영상.
다음 계획
Match 케이스 확인.
타일 폭파.
'GameDevelopmentDiary > PuzzleGame' 카테고리의 다른 글
3 Match 장르 게임 2 (4-6일차 총 10시간) (0) | 2022.07.30 |
---|---|
3 Match 장르 게임 1 (1-3일차 총 9시간) (0) | 2022.06.26 |