공부/유니티 디펜스 게임 만들기
Ground
원클릭쓰리버그
2022. 3. 12. 17:33
728x90
오늘의 작업
- 게임상 땅을 만든다.
- 땅 꼭지점 4개의 위치를 받아 저장한다.
- 꼭지점의 기준으로 Grid를 생성한다.
- 이 정보를 통해 길찾기를 몬스터가 가능하게 만든다.
#1 그라운드 생성
Matrial은 AssetStore에서 무료로 받아 사용한다
Plan은 Gizmos 기준으로 2x2이므로 총 4개의 노드를 잡아 먹는다고 생각했을때,
가로 9 세로 19 Plan을 만들었다.
그러므로 Tower을 1x1로 만들었다고 가정하고
총 가로 18개, 세로 38개로 만들 수 있다.
이러한 가정이 맞을려면,
오브젝트에 대한 크기를 1x1로 고정하여 생성할 수 있어야한다.
#2 땅 꼭지점 4개의 위치를 받아 저장한다.
#3 꼭지점 기준으로 Grid를 생성한다.
enum Vertex
{
LEFT_DOWN,
LEFT_UP,
RIGHT_DOWN,
RIGHT_UP,
MAX
}
Vector3[] vertices;
private void Awake()
{
nodeRadius = 0.5f;
nodeDiameter = nodeRadius * 2f;
Set_Vertex();
gridSize = new Vector2(Mathf.Abs(vertices[(int)Vertex.LEFT_DOWN].x - vertices[(int)Vertex.RIGHT_DOWN].x),
Mathf.Abs(vertices[(int)Vertex.LEFT_DOWN].z - vertices[(int)Vertex.LEFT_UP].z));
gridXCount = Mathf.RoundToInt(gridSize.x / nodeDiameter);
gridYCount = Mathf.RoundToInt(gridSize.y / nodeDiameter);
CreateGrid();
}
void Set_Vertex()
{
vertices = new Vector3[(int)Vertex.MAX];
vertices[(int)Vertex.LEFT_DOWN] = new Vector3(-40 - nodeRadius, 0, -30 - nodeRadius);
vertices[(int)Vertex.LEFT_UP] = new Vector3(-40 - nodeRadius, 0, 190 + nodeRadius);
vertices[(int)Vertex.RIGHT_UP] = new Vector3(40 + nodeRadius, 0, 190 + nodeRadius);
vertices[(int)Vertex.RIGHT_DOWN] = new Vector3(40 + nodeRadius, 0, 30 + nodeRadius);
}
각 점을 저장하여, 꼭지점 간의 거리를 측정한다.
# 4 최종
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class _Grid : MonoBehaviour
{
enum Vertex
{
LEFT_DOWN,
LEFT_UP,
RIGHT_DOWN,
RIGHT_UP,
MAX
}
public LayerMask unwalkableMask;
Node[,] grid;
Vector3[] vertices;
Vector2 gridSize;
float nodeRadius; //노드 반지름
float nodeDiameter; //노드 지름
int gridXCount, gridYCount; //Grid X축 Node 갯수, Grid Y축 Node 갯수
// 맵의 꼭지점을 위치를 받아 Grid의 갯수를 확정시킨다.
//전체 Node 크기값
public int MaxSize { get => gridXCount * gridYCount; }
private void Awake()
{
nodeRadius = 0.5f;
nodeDiameter = nodeRadius * 2f;
Set_Vertex();
gridSize = new Vector2(Mathf.Abs(vertices[(int)Vertex.LEFT_DOWN].x - vertices[(int)Vertex.RIGHT_DOWN].x),
Mathf.Abs(vertices[(int)Vertex.LEFT_DOWN].z - vertices[(int)Vertex.LEFT_UP].z));
gridXCount = Mathf.RoundToInt(gridSize.x / nodeDiameter);
gridYCount = Mathf.RoundToInt(gridSize.y / nodeDiameter);
CreateGrid();
}
void Set_Vertex()
{
vertices = new Vector3[(int)Vertex.MAX];
vertices[(int)Vertex.LEFT_DOWN] = new Vector3(-40 - nodeRadius, 0, -30 - nodeRadius);
vertices[(int)Vertex.LEFT_UP] = new Vector3(-40 - nodeRadius, 0, 190 + nodeRadius);
vertices[(int)Vertex.RIGHT_UP] = new Vector3(40 + nodeRadius, 0, 190 + nodeRadius);
vertices[(int)Vertex.RIGHT_DOWN] = new Vector3(40 + nodeRadius, 0, 30 + nodeRadius);
}
public List<Node> GetNearByNode(Node currentNode)
{
List<Node> NearByNodes = new List<Node>();
// 해당되는 노드의 붙어있는 노드를 체크하여 List에 담는다.
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <= 1; y++)
{
// 본인 자신이면 넘어간다.
if (x == 0 && y == 0)
continue;
int check_X = currentNode.gridX + x;
int check_Y = currentNode.gridY + y;
// 범위내 주변노드가 맞다면 List에 저장한다.
if ((0 <= check_X && check_X < gridXCount) &&
(0 <= check_Y && check_Y < gridYCount))
NearByNodes.Add(grid[check_X, check_Y]);
}
}
return NearByNodes;
}
private void CreateGrid()
{
grid = new Node[gridXCount, gridYCount];
Vector3 worldBottomLeft = transform.position - new Vector3((gridSize.x * 0.5f), 0, (gridSize.y * 0.5f));
for (int x = 0; x < gridXCount; x++)
{
for (int y = 0; y < gridYCount; y++)
{
Vector3 worldPosition = worldBottomLeft + new Vector3((x * nodeDiameter + nodeRadius), 0, (y * nodeDiameter + nodeRadius));
bool walkable = !(Physics.CheckSphere(worldPosition, nodeRadius, unwalkableMask));
grid[x, y] = new Node(walkable, worldPosition, x, y);
}
}
}
public Node GetNodeFromWorldPosition(Vector3 WP)
{
float percen_X = (WP.x + gridSize.x * 0.5f) / gridSize.x;
float percen_Y = (WP.z + gridSize.y * 0.5f) / gridSize.y;
percen_X = Mathf.Clamp01(percen_X);
percen_Y = Mathf.Clamp01(percen_Y);
int x = Mathf.RoundToInt((gridXCount - 1) * percen_X);
int y = Mathf.RoundToInt((gridYCount - 1) * percen_Y);
return grid[x, y];
}
private void OnDrawGizmos()
{
Gizmos.DrawWireCube(transform.position, new Vector3(gridSize.x, 1f, gridSize.y));
}
}