728x90
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Block{
public int type;
public bool vis;//visible, invisible
public GameObject obj;
public Block(int _type, bool _vis, GameObject _blockobj){
type = _type;
vis = _vis;
obj = _blockobj;
}
}
public class MapGenerator : MonoBehaviour
{
[Header("[Blocks]")]
public GameObject BlocksParents;
public GameObject B_DirtPrefab;
public GameObject B_BedRockPrefab;
public GameObject B_DiamondPrefab;
public GameObject B_GrassPrefab;
public GameObject B_SnowPrefab;
[Header("[Size Values]")]
static public int Width_x = 125;
static public int Width_z = 125;
static public int height = 125;
[Header("[Map Values]")]
public int[] groundArea;
public float GroundHeightOffset = 10;//맵을 띄워주는 변수
private float seed = 1;
[Header("[perlin noise]")]
public float Wavelength = 0;
public float Amplitude = 0;
public Block[,,] worldBolck = new Block[Width_x,height,Width_z];
//private List<GameObject> BlockList = new List<GameObject>();
// Start is called before the first frame update
void Start()
{
StartCoroutine(MapInit());
}
// Update is called once per frame
void Update()
{
}
IEnumerator InitGame(){
//지형 만들기
yield return StartCoroutine(MapInit());
//구름 만들기
//동굴 만들기
}
IEnumerator MapInit(){
//seed = (int)Random.Range(0,100);
for(int x=0;x <Width_x; x++){
for(int z = 0;z<Width_z;z++){
float xCoord = (x + seed) / Wavelength;
float zCoord = (z + seed) / Wavelength;
int y = (int)(Mathf.PerlinNoise(xCoord, zCoord) * Amplitude + GroundHeightOffset);
Vector3 pos = new Vector3(x,y,z);
StartCoroutine(CreateBlock(y,pos,true));
while(y > 0)
{
//지면아래에도 보이지 않는 블럭들을 배열에 넣는 작업
//실제로 객체는 만들어지지 않는다.
//0보다 큰 객체를 집어넣어주는 작업
//땅을 팠을 때 필요하기 때문(보이지않지만 값이 들어가있어야 불러올 수 있다)
y--;
pos = new Vector3(x,y,z);
StartCoroutine(CreateBlock(y,pos,false));
}
}
}
yield return null;
}
IEnumerator CreateBlock(int y, Vector3 blockpos, bool visual){
//보여지는 부분만 그려야 부하가 덜 걸린다.
//땅을 파면 판 부분만 보여지게 된다.
if(y > groundArea[0]){
if(visual){
GameObject BlockObj = (GameObject)Instantiate(B_SnowPrefab, blockpos, Quaternion.identity);
worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z] = new Block(1,visual,BlockObj);
}
else{
worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z] = new Block(1,visual,null);
}
}
else if(y>groundArea[1]){
if(visual){
GameObject BlockObj = (GameObject)Instantiate(B_GrassPrefab, blockpos, Quaternion.identity);
worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z] = new Block(2,visual,BlockObj);
}
else{
worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z] = new Block(2,visual,null);
}
}
else{
if(visual){
GameObject BlockObj = (GameObject)Instantiate(B_DirtPrefab, blockpos, Quaternion.identity);
worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z] = new Block(3,visual,BlockObj);
}
else{
worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z] = new Block(3,visual,null);
}
}
//0부터 7층
//이미 생성된 오브젝트를 지우고 그 자리를 광물로 대체함.
if(y > 0 && y < 7 && Random.Range(0,100) < 1){
if(worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z].obj != null){
Destroy(worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z].obj);
}
if(visual)
{
GameObject BlockObj = (GameObject)Instantiate(B_DiamondPrefab, blockpos, Quaternion.identity);
worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z] = new Block(4, visual, BlockObj);
}
else{
worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z] = new Block(4, visual, null);
}
}
//0층
if(y == 0){
if(visual){
GameObject BlockObj = (GameObject)Instantiate(B_BedRockPrefab, blockpos, Quaternion.identity);
worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z] = new Block(5,visual,BlockObj);
}
else{
worldBolck[(int)blockpos.x, (int)blockpos.y, (int)blockpos.z] = new Block(5,visual,null);
}
}
yield return null;
}
}
저번 코드에서 아래 코루틴 부분을 수정하였다.
지형을 그린다면 높낮이가 발생할텐데 이 높낮이에 따라서 블록의 종류를 바꿔준다.
이때 바꿔 줄 높이를 가진 배열을 인스팩터에서 쉽게 바꾸기 위하여 public배열을 사용하였다.
그리고 블록의 정보를 담기 위한 worldBlocks배열을 생성하였다.
이 블록에 좌표값이 해당 블록의 키값이 되고 동시에 좌표값이 되게 하여 블록을 쉽게 찾을 수 있게 하였다.
그리고 블록에 대한 클래스를 선언하였다.
public class Block{
public int type;
public bool vis;//visible, invisible
public GameObject obj;
public Block(int _type, bool _vis, GameObject _blockobj){
type = _type;
vis = _vis;
obj = _blockobj;
}
}
블록들의 타입과 보이는지 여부, 그리고 블록의 프리팹을 담을 클래스를 선언하였다.
코루틴 함수를 단계적으로 호출하여 블록이 생성될 때 생기는 부하들을 최대한 낮추었다.
728x90
'Develop > Imitation_MineCraft' 카테고리의 다른 글
[Imitation_MineCraft] 맵 생성하기1 (0) | 2022.12.01 |
---|