유니티
로그라이크 - BoardManager.cs
hololol
2019. 6. 24. 11:08
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System; //자동완성으로 SerializeField를 쓰려면 이 namespace 써야함
using Random = UnityEngine.Random; //랜덤으로 위치를 정해야함
public class BoardManager : MonoBehaviour
{
[SerializeField]
public class Count
{
//필드(변수), 생성자(초기값), 메소드
public int minCount; //최대값
public int maxCount; //최소값
public Count(int min, int max) //생성자, min max를 초기값으로
{
minCount = min;
maxCount = max;
}
}
public int columns = 8; //열의 개수, 보드판의 열
public int rows = 8; //보드판의 행
//배열은 0번부터 시작하니 보드판의 위치는 0~7 까지임
// (7,7)
//(0,0)
public Count wallCount = new Count(5, 9);//Count의 클래스를 가지고 값을 선언한다, 생성자로 값 초기화
public Count foodCount = new Count(1, 5); //food는 1개부터 5개까지
public GameObject exit;
public GameObject[] floorTiles; //바닥의 종류를 랜덤으로 결정
public GameObject[] wallTiles; //벽(장애물)의 종류를 랜덤으로 결정
public GameObject[] foodTiles; //food
public GameObject[] outerwallTiles; //바깥쪽 벽, 절대로 넘어갈 수 없는 outwall
public GameObject[] enemyTiles;
//List의 장점. 삽입 삭제가 용이함. 배열과 똑같은 존재
List<Vector3> gridPositions = new List<Vector3>();//위치 정보를 담음, 생성자를 이용해 만듦, 위치가 비어있지 않은가
Transform boardHolder;//보드를 정리해주는 역할
//게임이 시작될 때 마다 호출
void InitializeList() //위치정보를 넣고 초기화하겠다
{
gridPositions.Clear(); //리스트를 지움
for (int x = 1; x < columns - 1; x++)//1~6까지, x값
{
for (int y = 1; y < rows - 1; y++)//1~6까지, y값
{
gridPositions.Add(new Vector3(x, y, 0)); //List는 Add. 2D니까 z는0, 위치정보를 grid에 넣음
}
}
}
//보드판 만들기. 외벽과 안쪽 바닥을 특정한 위치에 생성한다
void BoardSetup()
{
boardHolder = new GameObject("boardHolder").transform; //대신 스크립트로
//외벽은 (-1,-1) 부터
for (int x = -1; x < columns + 1; x++)
{
for (int y = -1; y < rows + 1; y++)
{
//floor중에 랜덤으로 오브젝트 생성
GameObject obj = floorTiles[Random.Range(0, floorTiles.Length)];
//x가 -1이거나 colums가 가장 바깥쪽이거나 y가 -1이거나, y가 rows랑 같다면
if (x == -1 || x == columns || y == -1 || y == rows)
//obj에 바깥쪽 벽이 생성되도록 해야함
obj = outerwallTiles[Random.Range(0, outerwallTiles.Length)];
//obj를 생성한다
GameObject _object = Instantiate(obj, new Vector3(x, y, 0), Quaternion.identity);//임시변수, 타일 까는거니 회전필요x
_object.transform.SetParent(boardHolder);//boardHolder가 부모가 되도록 선언
}
}
}
//Vector3의 반환형을 가지는 함수
Vector3 RandomPosition()
{
//(1,1)~(6,6) 36개의 위치정보를 담는다
int randomIndex = Random.RandomRange(0, gridPositions.Count);//랜덤위치
Vector3 pos = gridPositions[randomIndex]; //List의 gridPosition을 pos에 저장.
gridPositions.RemoveAt(randomIndex); //삭제
return pos; //gridPosition의 pos 리턴
}
//배치
void LayoutObjectAtRandom(GameObject[] tileArray, Count count)
{
//Count가 가지는 최대, 최소 중에 랜덤으로 수를 결정
int objectCount = Random.Range(count.minCount, count.maxCount + 1);
//+1을 안쓰면 만약 5,9면 5~8밖에 안생김 그래서 +1을 써야함
for (int i = 0; i < objectCount; i++) //objectCount만큼 반복해서 생성
{
//메소드를 호출해서 위치하나를 가져온다
Vector3 pos = RandomPosition(); //새 위치 랜덤으로 받고
GameObject tileChoose = tileArray[Random.Range(0, tileArray.Length)];
//tileArray의 길이보다 작은만큼 random으로 타일을 고른다
Instantiate(tileChoose, pos, Quaternion.identity);
}
}
//1단계 2단계 3단계 레벨을 매개변수로 받는다
public void SetupScene(int level)
{
int num = (int)Mathf.Log(level, 2); //로그2의레벨. 1~3까지는 한마리, 4~8은 두마리.
Count enemyCount = new Count(num, num);
BoardSetup();
InitializeList();
LayoutObjectAtRandom(wallTiles, wallCount);
LayoutObjectAtRandom(foodTiles, foodCount); //foodTiles의 최대 최소 중 랜덤으로 만들어라
LayoutObjectAtRandom(enemyTiles, enemyCount);
Instantiate(exit, new Vector3(columns - 1, rows - 1), Quaternion.identity); //exit 생성
}
}