Unity에서 Grid System은 퍼즐, 보드 게임에서 많이 사용된다.
가로 길이(width)와 세로 길이(height)가 있는 2차원 좌표계의 게임 보드를 만들어보자.
1. 개념 구현
Grid class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
public class TestGrid
{
private int _width;
private int _height;
private int _cellSize;
private int[,] _gridArray;
private TextMesh[,] _textMeshes;
public TestGrid(int width, int height, int cellSize)
{
_width = width;
_height = height;
_cellSize = cellSize;
_gridArray = new int[width, height];
_textMeshes = new TextMesh[width, height];
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
_gridArray[x, y] = 0;
var position = GetWorldPosition(x, y);
// 현재 위치의 값을 TextMesh로 나타내준다.
_textMeshes[x, y] = SUtility.CreateTextToWorld(_gridArray[x, y].ToString(),
position + new Vector3(cellSize, cellSize) * 0.5f, 20, Color.white);
// 테두리를 그려준다
Debug.DrawLine(GetWorldPosition(x, y), GetWorldPosition(x + 1, y), Color.white, 999);
Debug.DrawLine(GetWorldPosition(x, y), GetWorldPosition(x, y + 1), Color.white, 999);
}
}
}
private Vector3 GetWorldPosition(int x, int y)
{
return new Vector3(x, y) * _cellSize;
}
}
|
cs |
간단하게 Grid System을 구현했다.
width와 height를 받아 width * height 크기만큼의 int형 2차원 배열을 만들었고,
cellSize의 간격을 지닌 격자를 생성한다.
보기 쉽게 각 셀의 위치에 TextMesh를 지닌 Object를 배치해 현재 좌표의 value를 나타내준다.
User Input과 Interactive하게 동작하도록 추가해보자
클릭시 value += 1을 적용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class TestGrid
{
...
// worldPosition을 cellSize로 나누어 grid에서의 위치를 구한다.
private void GetXY(Vector3 position, out int x, out int y)
{
x = Mathf.FloorToInt(position.x / _cellSize);
y = Mathf.FloorToInt(position.y / _cellSize);
}
public void SetValue(Vector3 position, int value)
{
int x, y;
GetXY(position, out x, out y);
_gridArray[x, y] = value;
_textMeshes[x, y].text = value.ToString();
}
public int GetValue(Vector3 position)
{
int x, y;
GetXY(position, out x, out y);
return _gridArray[x, y];
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class GameManager : MonoBehaviour
{
private TestGrid _grid;
void Start()
{
_grid = new TestGrid(10, 10, 5);
}
private void Update()
{
if (Input.GetMouseButtonUp(0))
{
var worldPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
_grid.SetValue(worldPosition, _grid.GetValue(worldPosition) + 1);
}
}
}
|
cs |
클릭(정확히는 MouseButtonUp)을 했을 때 Input.mousePosition을 기준으로 해당 좌표에 해당하는 값을 1씩 더해준다.
2. GameObject로 GameBoard 구현
이번에는 실제 게임에 적용할 수 있도록 GameObject로 Grid 형식의 게임판을 만들어보자.
먼저 하나의 칸을 나타내는 Tile class를 만든다.
Tile에는 위치를 나타내는 x, y와 값을 나타내는 _value, 그리고 값을 표시해줄 Text component가 들어있다.
이 Tile sciprt를 UI Button에 추가하고, Button의 OnClick Listener에 Tile.OnClick()을 추가했다.
그리고 Prefab으로 저장.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public class Tile : MonoBehaviour
{
public int x, y;
private int _value;
private Text _valueText;
private void Start()
{
_valueText = GetComponentInChildren<Text>();
}
public void Initialize(int x, int y)
{
this.x = x;
this.y = y;
}
public void OnClick()
{
_value += 1;
if (_valueText != null)
{
_valueText.text = _value.ToString();
}
}
}
|
cs |
다음으로 Tile을 관리할 Board를 만들고,
Tile Prefab을 width, height에 맞게 생성/배치한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public class Board : MonoBehaviour
{
public int width, height;
public GameObject tilePrefab;
private Tile[,] _tiles;
private void Start()
{
_tiles = new Tile[width, height];
Initialize();
}
private void Initialize()
{
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
var tileObject = Instantiate(tilePrefab, transform);
var tile = tileObject.GetComponent<Tile>();
tile.Initialize(x, y);
tile.transform.localPosition = new Vector2(x * tile.GetComponent<RectTransform>().sizeDelta.x,
y * tile.GetComponent<RectTransform>().sizeDelta.y);
}
}
}
}
|
cs |
Board를 5*5로 생성한 결과
각 Tile을 클릭시 값이 +1된다.
<참고>
Code Monkey - https://youtu.be/waEsGu--9P8
'Unity & C#' 카테고리의 다른 글
Grid System (3) - A* Pathfinding (0) | 2020.05.30 |
---|---|
Grid System (2) - 미로 만들기 (Maze Algorithm) (0) | 2020.05.22 |
Gyroscope Input (Unity Remote) (0) | 2020.05.10 |