Top.Mail.Ru
Ответы
Аватар пользователя
Аватар пользователя
Аватар пользователя
Аватар пользователя
Unity
+4

Помогите со скриптом на 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)

);

}

}

По дате
По рейтингу
Аватар пользователя
Мастер
3нед
Изменено

Реализуй пул объектов. Понимаешь, операции создания и удаления объектов КРАЙНЕ затратны по производительности. Поэтому тебе стоит за раз создать, к примеру, 20 чанков (перед загрузкой сцены) с использованием паттерна проектирования "пул объектов" и просто менять позицию этих чанков и включать их через метод SetActive. Ну прочитай про эту концепцию, это точно тебе поможет.

Просто создаешь 10 (или сколько нужно но это более оптимально. Для большей прорисовки больше чанков) чанков на сцене в выключенном состоянии, и перед операцией "создания" чанка ты меняешь его позицию, ну и какие-то там характеристики: высоту или ширину, и потом включаешь объект. К слову в ютубе вроде было полно гайдов которые очень хорошо и с наглядными примерами показывают реализацию данного паттерна.