/// <summary> /// 로딩 되어 있는 청크들만 매개변수로 넣어준다. /// 그 청크안의 타일들을 순차적으로 꺼준다. /// </summary> /// <param name="chunk"></param> IEnumerator UnLoadChunk(JH_Chunk chunk) { if (chunk == null) { yield break; } Vector2 diff = chunk.pos - playerChunk.pos; // 플레이어와 근접한 청크라면 언로딩 하지 않음. if (Mathf.Abs(diff.x) < 2 && Mathf.Abs(diff.y) < 2) { yield break; } int i, unloaded = 0; for (i = 0; i < chunk.tiles.Count; i++) { chunk.tiles[i].SetActive(false); unloaded++; if (unloaded > itemsPerFrame) { yield return(waitFrame); unloaded = 0; } } loadedChunks.Remove(chunk); chunk.active = false; }
void ChunkLoading() { Vector2Int pos = new Vector2Int((int)GM.PlayerPos.x, (int)GM.PlayerPos.y); //로딩 범위 설정 //플레이어 청크 좌표 int playerX = pos.x / JH_Chunk.chunkScale; int playerY = pos.y / JH_Chunk.chunkScale; playerChunk = loadedChunks.Find(temp => temp.pos == new Vector2(playerX, playerY)); //청크 로딩 //플레이어가 있는 청크는 한번에 로딩 InstLoadChunk(new JH_Chunk(new Vector2Int(playerX, playerY))); //주변 청크들은 몇프레임 걸쳐서 로딩 for (int x = -1; x <= 1; x++) { StartCoroutine(LoadChunk(new JH_Chunk(new Vector2Int(x + playerX, playerY + 1)))); StartCoroutine(LoadChunk(new JH_Chunk(new Vector2Int(x + playerX, playerY - 1)))); } StartCoroutine(LoadChunk(new JH_Chunk(new Vector2Int(playerX + 1, playerY)))); StartCoroutine(LoadChunk(new JH_Chunk(new Vector2Int(playerX - 1, playerY)))); //청크 언로딩 for (int i = loadedChunks.Count - 1; i >= 0; i--) { StartCoroutine(UnLoadChunk(loadedChunks[i])); } }
void InstLoadChunk(JH_Chunk chunk) { if (loadedChunks.Exists(temp => temp.pos == chunk.pos)) { return; } JH_Chunk c = spawnedChunks.Find(temp => temp.pos == chunk.pos); // 이미 존재하면 액티브만 켜줌 if (c != null) { c.SetActiveAll(true); loadedChunks.Add(chunk); return; } //미리 깔아놓는 변수들 int x, y; Vector2Int pos; GameObject obj; //로딩 범위 설정 int minX = chunk.startPos.x; int maxX = chunk.endPos.x; int minY = chunk.startPos.y; int maxY = chunk.endPos.y; //로딩 범위 설정 //존재 안하면 생성해줌 for (x = minX; x < maxX; x++) { for (y = minY; y < maxY; y++) { //Debug.Log($"x : {x}, y : {y}"); // 공백이면 넘어감 if (allTiles[y, x] < 0) { continue; } //pos : 배열에서의 좌표 pos = new Vector2Int(x, y); //새로 생성함 //Debug.Log($"x : {x} y : {y} allTiles[y, x] : {allTiles[y, x].ToString()}"); obj = SpawnTile(x, y, allTiles[y, x]); chunk.tiles.Add(obj); } } spawnedChunks.Add(chunk); loadedChunks.Add(chunk); }
/* * IEnumerator LoadTile(GameObject prefab, int count, int frames) * { * int itemsPerFrame = Mathf.FloorToInt(count / frames); * int spawned = 0; * while (spawned < count) * { * for (int i = 0; i < itemsPerFrame && spawned < count; i++) * { * Instantiate(prefab); * spawned++; * } * yield return new WaitForEndOfFrame(); * } * }*/ // 배열에서 해당 청크의 부분을 전부 돌면서 타일을 생성함 IEnumerator LoadChunk(JH_Chunk chunk) { //미리 깔아놓는 변수들 int x, y, spawnedInThisFrame = 0; GameObject obj; Vector2Int pos; //생성된 청크들 중에서 해당 청크가 있는지 확인 JH_Chunk c = spawnedChunks.Find(temp => temp.pos == chunk.pos); //있으면 그 청크 로딩 if (c != null) { //이미 켜져있으면 바로 나감 if (c.active) { yield break; } for (int i = 0; i < c.tiles.Count; i++) { c.tiles[i].SetActive(true); spawnedInThisFrame++; // 프레임당 생성 개수 채웠으면 if (spawnedInThisFrame > itemsPerFrame) { yield return(waitFrame); spawnedInThisFrame = 0; } } loadedChunks.Add(c); c.active = true; //로딩 끝 yield break; } //로딩 범위 설정 int minX = chunk.startPos.x; int maxX = chunk.endPos.x; int minY = chunk.startPos.y; int maxY = chunk.endPos.y; //로딩 범위 설정 //청크 없으면 새로 만듦 for (x = minX; x < maxX; x++) { for (y = minY; y < maxY; y++) { //Debug.Log($"x : {x}, y : {y}, startPos : {minX}, endPos : {maxX}"); // 공백이면 넘어감 if (allTiles[y, x] < 0) { continue; } //해당 위치에 타일이 있는지 체크 //pos : 배열에서의 좌표 pos = new Vector2Int(x, y); //Debug.Log($"x : {x} y : {y} allTiles[y, x] : {allTiles[y, x].ToString()}"); obj = SpawnTile(x, y, allTiles[y, x]); chunk.tiles.Add(obj); spawnedInThisFrame++; //해당 프레임에 로딩이 끝나면 다음 프레임으로 로딩을 넘김 if (spawnedInThisFrame >= itemsPerFrame) { yield return(waitFrame); spawnedInThisFrame = 0; } } } spawnedChunks.Add(chunk); loadedChunks.Add(chunk); }