


Помогите со скриптом на Unity (C#, Unity Engine)
Сделал скрипт для прорисовки чанков в 2d мире. Вроде всё работает без костылей, но лагает. Проверьте скрипт, может чего лишнего добавил(
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChunkLoader : MonoBehaviour
{
[System.Serializable]
public class ChunkInfo
{
public Vector2Int coord; // Координаты чанка
public GameObject prefab; // Префаб чанка
}
[Header("Основные настройки")]
public Transform loadingTarget; // Цель отслеживания (игрок)
public float chunkWidth = 50f; // Ширина чанка
public float chunkHeight = 25f; // Высота чанка
public int loadRadius = 1; // Радиус загрузки
[Header("База префабов")]
public List<ChunkInfo> chunkDatabase = new List<ChunkInfo>(); // Только указанные вами чанки
public Transform chunksParent; // Родитель для чанков
private Dictionary<Vector2Int, GameObject> activeChunks = new Dictionary<Vector2Int, GameObject>();
private Vector2Int lastPlayerChunk;
private bool isProcessing = false;
void Start()
{
if (!loadingTarget && Camera.main != null)
loadingTarget = Camera.main.transform;
if (loadingTarget == null)
{
Debug.LogError("Не назначен объект для отслеживания!");
return;
}
// Первоначальная загрузка чанков
lastPlayerChunk = CalculatePlayerChunk();
LoadInitialChunks();
}
void LoadInitialChunks()
{
// Загружаем все чанки в начальном радиусе
for (int x = -loadRadius; x <= loadRadius; x++)
{
for (int y = -loadRadius; y <= loadRadius; y++)
{
Vector2Int coord = new Vector2Int(
lastPlayerChunk.x + x,
lastPlayerChunk.y + y
);
TryLoadChunk(coord);
}
}
}
void Update()
{
if (loadingTarget == null) return;
Vector2Int currentChunk = CalculatePlayerChunk();
// Обновляем только при смене чанка
if (currentChunk != lastPlayerChunk && !isProcessing)
{
lastPlayerChunk = currentChunk;
StartCoroutine(UpdateChunks());
}
}
IEnumerator UpdateChunks()
{
isProcessing = true;
// 1. Определяем необходимые координаты
HashSet<Vector2Int> neededCoords = new HashSet<Vector2Int>();
for (int x = -loadRadius; x <= loadRadius; x++)
{
for (int y = -loadRadius; y <= loadRadius; y++)
{
neededCoords.Add(new Vector2Int(
lastPlayerChunk.x + x,
lastPlayerChunk.y + y
));
}
}
// 2. Удаляем чанки вне зоны видимости
List<Vector2Int> toRemove = new List<Vector2Int>();
foreach (var coord in activeChunks.Keys)
{
if (!neededCoords.Contains(coord))
{
Destroy(activeChunks[coord]);
toRemove.Add(coord);
}
}
foreach (var coord in toRemove) activeChunks.Remove(coord);
// 3. Загружаем новые чанки (только из базы данных)
foreach (var coord in neededCoords)
{
if (!activeChunks.ContainsKey(coord))
{
TryLoadChunk(coord);
yield return null; // Пауза между загрузкой чанков
}
}
isProcessing = false;
}
void TryLoadChunk(Vector2Int coord)
{
// Ищем префаб в базе данных
foreach (var info in chunkDatabase)
{
if (info.coord == coord)
{
// Создаем чанк
Vector3 position = new Vector3(
coord.x * chunkWidth,
coord.y * chunkHeight,
0
);
GameObject newChunk = Instantiate(info.prefab, position, Quaternion.identity);
if (chunksParent) newChunk.transform.SetParent(chunksParent);
newChunk.name = $"Chunk_{coord.x}_{coord.y}";
activeChunks.Add(coord, newChunk);
break; // Прекращаем поиск после нахождения
}
}
}
Vector2Int CalculatePlayerChunk()
{
Vector3 pos = loadingTarget.position;
return new Vector2Int(
Mathf.RoundToInt(pos.x / chunkWidth),
Mathf.RoundToInt(pos.y / chunkHeight)
);
}
}
Ответ от RawMind AI Инструкция по оптимизации скрипта ChunkLoader: 1. Замена списка на словарь для базы данных Переведите `chunkDatabase` из списка в словарь, чтобы ускорить поиск префабов: ```csharp // Вместо List<ChunkInfo> используйте Dictionary<Vector2Int, GameObject> public Dictionary<Vector2Int, GameObject> chunkDatabase = new Dictionary<Vector2Int, GameObject>(); ``` Почему: Поиск по словарю происходит за O(1), а не O(n). Это ускорит метод `TryLoadChunk()`. 2. Удаление пауз в загрузке чанков Уберите `yield return null;` из цикла загрузки новых чанков: ```csharp // В IEnumerator UpdateChunks() foreach (var coord in neededCoords) { if (!activeChunks.ContainsKey(coord)) { TryLoadChunk(coord); // Удалить yield return null; } } ``` Почему: Каждый `yield` добавляет задержку на кадр. Для 9 чанков это 9 лишних кадров. 3. Оптимизация удаления ненужных чанков Используйте `ToList()` для итерации по ключам словаря: ```csharp // В IEnumerator UpdateChunks()