Unity에서 3-Match 퍼즐 그리드생성 코드 업데이트
안녕하세요! 이번에는 Unity에서 3-Match Grid 생성코드 업데이트 된 버전입니다.
Grid Manager 클래스 소개
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GridManager : MonoBehaviour
{
public int _gridHeight = 6;
public int _gridWidth = 6;
public GameObject grid1Sprite;
public GameObject grid2Sprite;
private int currentRowType = 1;
[SerializeField] private int _maxRows = 9;
[SerializeField] private SpawnManager spawnManager;
[SerializeField] private CharacterManager characterManager;
private void Start()
{
GenerateInitialGrid();
spawnManager.SpawnCharacters();
}
public void GenerateInitialGrid()
{
for (int y = 0; y < _gridHeight; y++)
{
for (int x = 0; x < _gridWidth; x++)
{
GameObject spritePrefab = (x + y) % 2 == 0
? grid1Sprite
: grid2Sprite;
GameObject cell =
Instantiate(spritePrefab, new Vector3(x, y, 0),
Quaternion.identity, transform);
if (!spawnManager.IsCharacterAtPosition(new Vector3(x, y, 0)))
{
int randomCharacterIndex = Random.Range(0,
characterManager.characterGroup.Count);
spawnManager.SpawnCharacterAtPosition
(randomCharacterIndex, x, y);
}
}
}
}
public void AddRow()
{
if (_gridHeight < _maxRows)
{
_gridHeight++;
// Move existing characters up
foreach (GameObject character in spawnManager.GetPooledCharacters())
{
if (character.activeInHierarchy)
{
Vector3 newPosition = character.transform.position;
newPosition.y += 1;
character.transform.position = newPosition;
}
}
// Create new row and spawn characters
for (int x = 0; x < _gridWidth; x++)
{
GameObject spritePrefab = (x + currentRowType) % 2 == 0
? grid1Sprite
: grid2Sprite;
Instantiate(spritePrefab, new Vector3(x, -1, 0),
Quaternion.identity, transform);
if (!spawnManager.IsCharacterAtPosition(new Vector3(x, -1, 0)))
{
int randomCharacterIndex =
Random.Range(0, characterManager.characterGroup.Count);
spawnManager.SpawnCharacterAtPosition
(randomCharacterIndex, x, -1);
}
}
// Move the entire grid up
foreach (Transform child in transform)
{
Vector3 newPosition = child.position;
newPosition.y += 1;
child.position = newPosition;
}
currentRowType = currentRowType == 1
? 2
: 1;
spawnManager.DeactivateCharactersOutsideGrid
(_gridWidth, _gridHeight);
}
}
}
저번과 달라진 점은 기존에는 Grid Manager에서 케릭터의 스폰관리를 함께 했다면, 이번에는 코드를 분리하여 케릭터 소환을 목적으로 하는 클래스를 새로 생성하였습니다.
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class SpawnManager : MonoBehaviour
{
[SerializeField]
private CharacterManager characterManager;
[SerializeField]
private GridManager gridManager;
[SerializeField]
private CharacterPool characterPool;
private int[] objectCounts = new int[5];
public void SpawnCharacters()
{
List<Vector2Int> availablePositions = new List<Vector2Int>();
for (int x = 0; x < gridManager._gridWidth; x++)
{
for (int y = 0; y < gridManager._gridHeight; y++)
{
availablePositions.Add(new Vector2Int(x, y));
}
}
int[] targetCounts = { 7, 7, 7, 7, 8 };
int[] currentCounts = new int[5];
while (availablePositions.Count > 0 && currentCounts.Sum() < 36)
{
int randomCharacterIndex =
Random.Range(0, characterManager.characterGroup.Count);
if (currentCounts[randomCharacterIndex] <
targetCounts[randomCharacterIndex])
{
int randomPositionIndex =
Random.Range(0, availablePositions.Count);
Vector2Int randomPosition =
availablePositions[randomPositionIndex];
availablePositions.RemoveAt(randomPositionIndex);
SpawnCharacterAtPosition(randomCharacterIndex,
randomPosition.x, randomPosition.y);
currentCounts[randomCharacterIndex]++;
}
}
}
public void SpawnCharacterAtPosition(int characterIndex, int x, int y)
{
Vector3 spawnPosition = new Vector3(x, y, 0);
if (!IsCharacterAtPosition(spawnPosition))
{
GameObject characterPrefab =
characterManager.characterGroup[characterIndex].gameObject;
GameObject pooledCharacter = characterPool.GetPooledCharacter();
if (pooledCharacter != null)
{
pooledCharacter.GetComponent<CharacterBase>().
Setup(characterPrefab.GetComponent<CharacterBase>());
pooledCharacter.transform.position = spawnPosition;
pooledCharacter.SetActive(true);
}
}
}
public List<GameObject> GetPooledCharacters()
{
return characterPool.GetPooledCharacters();
}
public bool IsCharacterAtPosition(Vector3 position)
{
foreach (GameObject character in characterPool.GetPooledCharacters())
{
if (character.activeInHierarchy
&& character.transform.position == position)
{
return true;
}
}
return false;
}
public void DeactivateCharactersOutsideGrid(int gridWidth, int gridHeight)
{
foreach (GameObject character in characterPool.GetPooledCharacters())
{
if (character.activeInHierarchy)
{
Vector3 position = character.transform.position;
if (position.x < 0
|| position.x >= gridWidth
|| position.y < 0
|| position.y >= gridHeight)
{
character.SetActive(false);
}
}
}
}
}
하지만, 케릭터의 위치가 바뀌어야 하지만 그 뒤의 Grid가 바뀌는 버그,,,