Я выпускаю сценарий оптимизации для моего учебного проекта, в котором я работаю. пытаюсь создать базовую функциональность Minecraft.
Я создал два метода для граничных кубов в кусках, которые гарантируют, что граничные кубы, покрытые с каждого направления другими кубами, не будут создавать экземпляры или, если они уже созданы, они будут деактивированы.
Проблема в том, что эти два метода < strong>содержат избыточный код, от которого я хочу избавиться, чтобы сделать этот скрипт чище.
Код: Выделить всё
private void BorderCubesOptimizationsOfNewChunk(CubeData newCubeData, Dictionary newChunkFieldData, Vector3 centerOfNeigbourChunk, Vector3 neighbourCubePosition, Border border, Corner corner)
{
Dictionary neighbourChunk = mapGenerator.dictionaryOfCentersWithItsChunkField[centerOfNeigbourChunk];
// WIP
if (corner != Corner.Null)
{
if (corner == Corner.XNegative_ZNegative)
{
}
else if (corner == Corner.XNegative_ZPositive)
{
}
else if (corner == Corner.XPositive_ZNegative)
{
}
else if (corner == Corner.XPositive_ZPositive)
{
}
return;
}
// If there is a Cube in New Chunk bellow New Cube, then return
if (!newChunkFieldData.ContainsKey(newCubeData.position - Vector3.up))
{
return;
}
// If there is a Cube in New Chunk above New Cube, then return
if (!newChunkFieldData.ContainsKey(newCubeData.position + Vector3.up))
{
return;
}
if (border != Border.XNegative)
{
// If there is a Cube in New Chunk at decremented X position, then return
if (!newChunkFieldData.ContainsKey(newCubeData.position - Vector3.right))
{
return;
}
}
else
{
// If there is a Cube in Neighbour Chunk at decremented X position, then return
if (!neighbourChunk.ContainsKey(neighbourCubePosition))
{
return;
}
}
if (border != Border.XPositive)
{
// If there is a Cube in New Chunk at incremented X position, then return
if (!newChunkFieldData.ContainsKey(newCubeData.position + Vector3.right))
{
return;
}
}
else
{
// If there is a Cube in Neighbour Chunk at incremented X position, then return
if (!neighbourChunk.ContainsKey(neighbourCubePosition))
{
return;
}
}
if (border != Border.ZNegative)
{
// If there is a Cube in New Chunk at decremented Z position, then return
if (!newChunkFieldData.ContainsKey(newCubeData.position - Vector3.forward))
{
return;
}
}
else
{
// If there is a Cube in Neighbour Chunk at decremented Z position, then return
if (!neighbourChunk.ContainsKey(neighbourCubePosition))
{
return;
}
}
if (border != Border.ZPositive)
{
// If there is a Cube in New Chunk at incremented Z position, then return
if (!newChunkFieldData.ContainsKey(newCubeData.position + Vector3.forward))
{
return;
}
}
else
{
// If there is a Cube in Neighbout Chunk at incremented Z position, then return
if (!neighbourChunk.ContainsKey(neighbourCubePosition))
{
return;
}
}
newCubeData.isCubeDataSurrounded = true;
}
Код: Выделить всё
private void BorderCubesOptimizationsOfNeighbourChunk(Dictionary newChunkFieldData, CubeData newCubeData, Vector3 centerOfNeigbourChunk, Vector3 neighbourCubePosition, Border border, Corner corner)
{
Dictionary neighbourChunk = mapGenerator.dictionaryOfCentersWithItsChunkField[centerOfNeigbourChunk];
// WIP
if (corner != Corner.Null)
{
if (true)
{
}
else if (true)
{
}
else if (true)
{
}
else if (true)
{
}
return;
}
// If there is a Cube in Neighbour Chunk bellow Neighbour Cube, then return
if (!neighbourChunk.ContainsKey(neighbourCubePosition - Vector3.up))
{
return;
}
// If there is a Cube in Neighbour Chunk bellow Neighbour Cube, then return
if (!neighbourChunk.ContainsKey(neighbourCubePosition + Vector3.up))
{
return;
}
if (border != Border.XNegative)
{
// If there is Cube in Neighbour Chunk at incremented X position, then return
if (!neighbourChunk.ContainsKey(neighbourCubePosition + Vector3.right))
{
return;
}
}
else
{
// If there is Cube in New Chunk at incremented X position, then return
if (!newChunkFieldData.ContainsKey(newCubeData.position))
{
return;
}
}
if (border != Border.XPositive)
{
// If there is Cube in Neighbour Chunk at decremented X position, then return
if (!neighbourChunk.ContainsKey(neighbourCubePosition - Vector3.right))
{
return;
}
}
else
{
// If there is Cube in New Chunk at decremented X position, then return
if (!newChunkFieldData.ContainsKey(newCubeData.position))
{
return;
}
}
if (border != Border.ZNegative)
{
// If there is Cube in Neighbour Chunk at incremented Z position, then return
if (!neighbourChunk.ContainsKey(neighbourCubePosition + Vector3.forward))
{
return;
}
}
else
{
// If there is Cube in New Chunk at incremented Z position, then return
if (!newChunkFieldData.ContainsKey(newCubeData.position))
{
return;
}
}
if (border != Border.ZPositive)
{
// If there is cube in Neighbour Chunk at decremented Z position, then return
if (!neighbourChunk.ContainsKey(neighbourCubePosition - Vector3.forward))
{
return;
}
}
else
{
// If there is cube in New Chunk at decremented Z position, then return
if (!newChunkFieldData.ContainsKey(newCubeData.position))
{
return;
}
}
neighbourChunk[neighbourCubePosition].cubeInstance.gameObject.SetActive(false);
Код: Выделить всё
private void OptimizeDataOfNewChunk(CubeData newCubeData, Vector3 centerOfUpcomingChunk, Dictionary newChunkFieldData)
{
Border border = Border.Null;
Corner corner = Corner.Null;
// Negative X border of actual chunk
// If actual cube postion is on border of actual chunk and if border chunk exist, optimalize borders of these two chunks
if ((newCubeData.position.x - (mapGenerator.gridSize.x / 2)) % mapGenerator.gridSize.x == 0)
{
if (mapGenerator.dictionaryOfCentersWithItsChunkField.ContainsKey(centerOfXPositiveNeighbourChunk))
{
border = Border.XPositive;
// WIP: X positive - Z positive corner
if (newCubeData.position.z == centerOfUpcomingChunk.z + Mathf.Ceil((float)mapGenerator.gridSize.x / 2.0f) - 1.0f)
{
}
// WIP: X positive - Z negative corner
else if (newCubeData.position.z == centerOfUpcomingChunk.z - Mathf.Ceil((float)mapGenerator.gridSize.x / 2.0f) + 1.0f)
{
}
BorderCubesOptimizationsOfNewChunk(newCubeData, newChunkFieldData, centerOfXPositiveNeighbourChunk, newCubeData.position + Vector3.right, border, Corner.Null);
BorderCubesOptimizationsOfNeighbourChunk(newChunkFieldData, newCubeData, centerOfXPositiveNeighbourChunk, newCubeData.position + Vector3.right, border, Corner.Null);
return;
}
}
// Positive X border of actual chunk
// If actual cube postion is on border of actual chunk and if border chunk exist, optimalize borders of these two chunks
else if ((newCubeData.position.x + (mapGenerator.gridSize.x / 2)) % mapGenerator.gridSize.x == 0)
{
if (mapGenerator.dictionaryOfCentersWithItsChunkField.ContainsKey(centerOfXNegativeNeighbourChunk))
{
border = Border.XNegative;
// WIP: X negative - Z positive corner
if (newCubeData.position.z == centerOfUpcomingChunk.z + Mathf.Ceil((float)mapGenerator.gridSize.z / 2.0f) - 1.0f)
{
}
// WIP: X negative - Z negative corner
else if (newCubeData.position.z == centerOfUpcomingChunk.z - Mathf.Ceil((float)mapGenerator.gridSize.z / 2.0f) + 1.0f)
{
}
BorderCubesOptimizationsOfNewChunk(newCubeData, newChunkFieldData, centerOfXNegativeNeighbourChunk, newCubeData.position + Vector3.left, border, Corner.Null);
BorderCubesOptimizationsOfNeighbourChunk(newChunkFieldData, newCubeData, centerOfXNegativeNeighbourChunk, newCubeData.position + Vector3.left, border, Corner.Null);
return;
}
}
// Negative Z border of actual chunk
// If actual cube postion is on border of actual chunk and if border chunk exist, optimalize borders of these two chunks
else if ((newCubeData.position.z - (mapGenerator.gridSize.x / 2)) % mapGenerator.gridSize.x == 0)
{
if (mapGenerator.dictionaryOfCentersWithItsChunkField.ContainsKey(centerOfZPositiveNeighbourChunk))
{
border = Border.ZPositive;
// Z positive - X positive corner
if (newCubeData.position.x == centerOfUpcomingChunk.x + Mathf.Ceil((float)mapGenerator.gridSize.x / 2.0f) - 1.0f)
{
}
// Z negative - X negative corner
else if (newCubeData.position.x == centerOfUpcomingChunk.x - Mathf.Ceil((float)mapGenerator.gridSize.x / 2.0f) + 1.0f)
{
}
BorderCubesOptimizationsOfNewChunk(newCubeData, newChunkFieldData, centerOfZPositiveNeighbourChunk, newCubeData.position + Vector3.forward, border, Corner.Null);
BorderCubesOptimizationsOfNeighbourChunk(newChunkFieldData, newCubeData, centerOfZPositiveNeighbourChunk, newCubeData.position + Vector3.forward, border, Corner.Null);
return;
}
}
// Postive Z border of actual chunk
// If actual cube postion is on border of actual chunk and if border chunk exist, optimalize borders of these two chunks
else if ((newCubeData.position.z + (mapGenerator.gridSize.x / 2)) % mapGenerator.gridSize.x == 0)
{
if (mapGenerator.dictionaryOfCentersWithItsChunkField.ContainsKey(centerOfZNegativeNeighbourChunk))
{
border = Border.ZNegative;
// Z negative - X positive corner
if (newCubeData.position.x == centerOfUpcomingChunk.x + Mathf.Ceil((float)mapGenerator.gridSize.x / 2.0f) - 1.0f)
{
}
// Z negative - X negative corner
else if (newCubeData.position.x == centerOfUpcomingChunk.x - Mathf.Ceil((float)mapGenerator.gridSize.x / 2.0f) + 1.0f)
{
}
BorderCubesOptimizationsOfNewChunk(newCubeData, newChunkFieldData, centerOfZNegativeNeighbourChunk, newCubeData.position + Vector3.back, border, Corner.Null);
BorderCubesOptimizationsOfNeighbourChunk(newChunkFieldData, newCubeData, centerOfZNegativeNeighbourChunk, newCubeData.position + Vector3.back, border, Corner.Null);
return;
}
}
DeactiavateSurroundedCubeData(newCubeData, newChunkFieldData);
}
Я знаю, что такое дженерики, и спокойно знаю, как использовать их на очень низком уровне, но раньше я не использовал их в более сложном коде. Я пытался найти документацию и видео, чтобы научиться использовать дженерики, но это не помогло мне даже убедиться, что я на правильном пути.
Также я попросил ChatGPT разделить эти два метода на один, используя дженерики, и ни один из его ответов ни на шаг не приблизил меня к решению этой головоломки. Я попробовал одну реализацию, которую она мне предоставила, но она дала мне внеочередной ответ, который делает дженерики метода OptimizeDataOfNewChunk, но я даже не использовал ее.
Однако, даже если я попытаюсь использовать дженерики для обобщения словарей, которые я использую как фрагменты, я не знаю, как обеспечить это для Соседних кубов или Новых кубов , будут оцененные операторы с соответствующими условиями.
Буду очень благодарен за советы по дизайну или ссылки на обучение материал, который предоставит мне эффективный способ решить эту проблему.
Подробнее здесь: https://stackoverflow.com/questions/789 ... rp-project