Помогите с оптимизацией
Добавлено: 05 дек 2018, 18:08
Делаю небольшую игру на основе процедурно-генерируемого мира, столкнулся с проблемой что при передвижении все чанки пытаются загрузиться за один кадр и из-за этого ловишь фриз на несколько секунд. В скрипте WorldGen видно, что я пытался разгрузить код с помощью карантина, но у меня не получилось. Прошу вашей помощи. Для полного представления вот проект *клик*
Сначала создаётся квадрат из чанков 9*9, по середине которого находится игрок, с помощью функции CreateChunk(), которая в циклах.
После создания всех чанков они начинают отрисовываться функцией Chunk.UpdateChunk()
Важное замечание: отрисовывать чанки надо начинать только после создания всех, чтобы на их стыке не было дыр.
При пересечении границ чанков весь квадрат из чанков 9*9 проверяется на наличие чанков вокруг игрока на этом расстоянии, если их не достаёт, то скрипт добавляет чанки и уничтожает те, которые находятся дальше этого расстояния.
Сначала создаётся квадрат из чанков 9*9, по середине которого находится игрок, с помощью функции CreateChunk(), которая в циклах.
После создания всех чанков они начинают отрисовываться функцией Chunk.UpdateChunk()
Важное замечание: отрисовывать чанки надо начинать только после создания всех, чтобы на их стыке не было дыр.
При пересечении границ чанков весь квадрат из чанков 9*9 проверяется на наличие чанков вокруг игрока на этом расстоянии, если их не достаёт, то скрипт добавляет чанки и уничтожает те, которые находятся дальше этого расстояния.
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WorldGen : MonoBehaviour {
public static List<Chunk> Chunks = new List<Chunk>();
public GameObject Player;
public GameObject Chunk;
Vector2 OldPlayerPos;
public Vector2 PlayerPos;
// Use this for initialization
void Start () {
for (int x = 0; x < 9; x++)
{
for (int z = 0; z < 9; z++)
{
CreateChunk(new Vector3((PlayerPos[0] - 4 + x) * 16, 0, (PlayerPos[1] - 4 + z) * 16));
}
}
foreach (Chunk Chunk in WorldGen.Chunks)
{
Chunk.UpdateChunk();
}
}
// Update is called once per frame
void Update () {
PlayerPos = new Vector2(Mathf.Floor(Player.transform.position.x / 16), Mathf.Floor(Player.transform.position.z / 16));
if (PlayerPos == OldPlayerPos) return;
StartCoroutine(Generate());
OldPlayerPos = PlayerPos;
}
IEnumerator Generate()
{
for (int x = 0; x < 9; x++)
{
for (int z = 0; z < 9; z++)
{
int i;
for (i = 0; i < Chunks.Count; i++)
{
if (Chunks[i].transform.position == new Vector3((PlayerPos[0] - 4 + x) * 16, 0, (PlayerPos[1] - 4 + z) * 16)) break;
}
if (i == Chunks.Count)
{
CreateChunk(new Vector3((PlayerPos[0] - 4 + x) * 16, 0, (PlayerPos[1] - 4 + z) * 16));
//yield return new WaitForSeconds(1);
}
}
}
for (int i = 0; i < Chunks.Count; i++)
{
Vector3 PlyPos = Player.transform.position;
PlyPos[1] = 0;
if (Vector3.Distance(PlyPos, Chunks[i].transform.position) > 120)
{
Destroy(Chunks[i].gameObject);
Chunks.RemoveAt(i);
//yield return new WaitForSeconds(1);
}
}
for (int i = 0; i < Chunks.Count; i++)
{
Chunks[i].UpdateChunk();
//yield return new WaitForSeconds(1);
}
yield return null;
}
void CreateChunk(Vector3 ChunkPos)
{
GameObject CreatedChunk = Instantiate(Chunk, ChunkPos, Quaternion.identity);
CreatedChunk.GetComponent<Chunk>().GenerateChunk();
}
}
using System.Collections.Generic;
using UnityEngine;
public class WorldGen : MonoBehaviour {
public static List<Chunk> Chunks = new List<Chunk>();
public GameObject Player;
public GameObject Chunk;
Vector2 OldPlayerPos;
public Vector2 PlayerPos;
// Use this for initialization
void Start () {
for (int x = 0; x < 9; x++)
{
for (int z = 0; z < 9; z++)
{
CreateChunk(new Vector3((PlayerPos[0] - 4 + x) * 16, 0, (PlayerPos[1] - 4 + z) * 16));
}
}
foreach (Chunk Chunk in WorldGen.Chunks)
{
Chunk.UpdateChunk();
}
}
// Update is called once per frame
void Update () {
PlayerPos = new Vector2(Mathf.Floor(Player.transform.position.x / 16), Mathf.Floor(Player.transform.position.z / 16));
if (PlayerPos == OldPlayerPos) return;
StartCoroutine(Generate());
OldPlayerPos = PlayerPos;
}
IEnumerator Generate()
{
for (int x = 0; x < 9; x++)
{
for (int z = 0; z < 9; z++)
{
int i;
for (i = 0; i < Chunks.Count; i++)
{
if (Chunks[i].transform.position == new Vector3((PlayerPos[0] - 4 + x) * 16, 0, (PlayerPos[1] - 4 + z) * 16)) break;
}
if (i == Chunks.Count)
{
CreateChunk(new Vector3((PlayerPos[0] - 4 + x) * 16, 0, (PlayerPos[1] - 4 + z) * 16));
//yield return new WaitForSeconds(1);
}
}
}
for (int i = 0; i < Chunks.Count; i++)
{
Vector3 PlyPos = Player.transform.position;
PlyPos[1] = 0;
if (Vector3.Distance(PlyPos, Chunks[i].transform.position) > 120)
{
Destroy(Chunks[i].gameObject);
Chunks.RemoveAt(i);
//yield return new WaitForSeconds(1);
}
}
for (int i = 0; i < Chunks.Count; i++)
{
Chunks[i].UpdateChunk();
//yield return new WaitForSeconds(1);
}
yield return null;
}
void CreateChunk(Vector3 ChunkPos)
{
GameObject CreatedChunk = Instantiate(Chunk, ChunkPos, Quaternion.identity);
CreatedChunk.GetComponent<Chunk>().GenerateChunk();
}
}