Метод неожиданно вызывается в Unity C#C#

Место общения программистов C#
Ответить
Anonymous
 Метод неожиданно вызывается в Unity C#

Сообщение Anonymous »

Я работаю над оптимизацией для учебного проекта, в котором воссоздаю базовые функции Minecraft.
Я успешно реализовал оптимизацию для граничных и угловых кубов блоков. . Когда игрок запускает процесс генерации чанка, кубы на границах и углах, полностью закрытые со всех сторон, либо отключаются (если они уже существуют), либо не создаются (если это новые кубы для нового чанка).
Чтобы сделать код чище, я решил перенести оптимизацию границ и углов куба в отдельные классы, каждый из которых наследуется от сценария MapOptimization. Я начал со сценария BorderOptimization и использовал действие onIsBorderCube для запуска BorderCubeOptimizationSequence. Я подписался на действие onIsBorderCube в методе Start() функции BorderOptimization. Хотя действие вызывается правильно, после завершения каждой допустимой итерации я сталкиваюсь с исключением NullReferenceException.
Исключение возникает сразу после завершения метода ProcessAllCubeDataOfUpcomingChunk. По какой-то причине метод ProcessAllCubeDataOfUpcomingChunk вызывается снова, но на этот раз действие onIsBorderCube имеет значение null, что приводит к сбою.
Сценарий MapOptimization ниже ⬇️
Скрипт не полный, я удалил другие элементы, чтобы предварительный просмотр был кратким. Если вы что-то пропустите, сообщите мне, и я добавлю это.

Код: Выделить всё

public class MapOptimization : MonoBehaviour
{
protected Action onIsBorderCube;

private void ProcessAllCubeDataOfUpcommingChunk(Dictionary newChunkFieldData, Vector3 centerOfNewChunk)
{
centerOfXNegativeNeighbourChunk = new Vector3(centerOfNewChunk.x - mapGenerator.gridSize.x, centerOfNewChunk.y, centerOfNewChunk.z);
centerOfXPositiveNeighbourChunk = new Vector3(centerOfNewChunk.x + mapGenerator.gridSize.x, centerOfNewChunk.y, centerOfNewChunk.z);
centerOfZNegativeNeighbourChunk = new Vector3(centerOfNewChunk.x, centerOfNewChunk.y, centerOfNewChunk.z - mapGenerator.gridSize.z);
centerOfZPositiveNeighbourChunk = new Vector3(centerOfNewChunk.x, centerOfNewChunk.y, centerOfNewChunk.z + mapGenerator.gridSize.z);

XNegativeCorner = centerOfNewChunk.x - Mathf.Ceil((float)mapGenerator.gridSize.x / 2.0f) + 1.0f;
XPositiveCorner = centerOfNewChunk.x + Mathf.Ceil((float)mapGenerator.gridSize.x / 2.0f) - 1.0f;
ZNegativeCorner = centerOfNewChunk.z - Mathf.Ceil((float)mapGenerator.gridSize.x / 2.0f) + 1.0f;
ZPositiveCorner = centerOfNewChunk.z + Mathf.Ceil((float)mapGenerator.gridSize.x / 2.0f) - 1.0f;

foreach (KeyValuePair newCubeData in newChunkFieldData)
{
OptimizeDataOfNewChunk(newCubeData.Value, centerOfNewChunk, newChunkFieldData);
}
}

private void OptimizeDataOfNewChunk(CubeData newCubeData, Vector3 centerOfNewChunk, Dictionary newChunkFieldData)
{
Border newChunkBorder = Border.Null;
if (isCubeAtBorder(newCubeData.position, ref newChunkBorder))
{
Corner newCubeCorner = Corner.Null;
if (isNewCubeAtCorner(newCubeData, ref newCubeCorner))
{
CornerCubeOptimizationSequence(newCubeData, centerOfNewChunk, newChunkBorder, newCubeCorner);
}
else
{
onIsBorderCube(newChunkFieldData, newCubeData, newChunkBorder);
}
}
else
{
DeactiavateSurroundedCubeData(newCubeData, newChunkFieldData);
}
}
}

Сценарий BorderOptimization ниже ⬇️
Скрипт не полный, я удалил другие элементы, чтобы сделать его предварительный просмотр кратким. Если вы что-то пропустите, сообщите мне, и я добавлю это.

Код: Выделить всё

public class BorderOptimization : MapOptimization
{
void Start()
{
Debug.Log("onIsBorder is subscribbed");
onIsBorderCube += BorderCubeOptimizationSequence;
}

private void BorderCubeOptimizationSequence(Dictionary newChunkFieldData, CubeData newCubeData, Border newChunkBorder)
{
Border neighbourChunkBorder = Border.Null;
Vector3 neighbourCubePosition = Vector3.zero;
Vector3 neighbourChunkCenter = Vector3.zero;

SetNeighborChunkValues(newChunkBorder, newCubeData.position, ref neighbourChunkBorder, ref neighbourCubePosition, ref neighbourChunkCenter);

if (!DoesNeighborChunkExist(neighbourChunkCenter))
{
return;
}

Dictionary neighbourChunkField = mapGenerator.dictionaryOfCentersWithItsChunkField[neighbourChunkCenter];
// Return if New Cube in New Chunk isn't surrounded with cubes from each sides
if (!IsBorderCubeSurrounded(newChunkFieldData, newCubeData.position, neighbourChunkField, neighbourCubePosition, newChunkBorder))
{
return;
}
newCubeData.isCubeDataSurrounded = true;

// Return if Neighbor Cube in Neighbor Chunk isn't surrounded with cubes from each sides
if (!IsBorderCubeSurrounded(neighbourChunkField, neighbourCubePosition, newChunkFieldData, newCubeData.position, neighbourChunkBorder))
{
return;
}
neighbourChunkField[neighbourCubePosition].cubeInstance.gameObject.SetActive(false);
}
}
Проблема, с которой я столкнулся, заключается не в том, что действие onIsBorderCube генерирует исключение NullReferenceException, а в том, что метод ProcessAllCubeDataOfUpcommingChunk вызывается дополнительный раз, чего не должно быть.
Проблема, с которой я столкнулся, заключается не в том, что действие onIsBorderCube вызывает исключение NullReferenceException, а в том, что метод ProcessAllCubeDataOfUpcommingChunk вызывается дополнительный раз, чего не должно быть.
p>
Шаги, которые я предпринял:
  • Я вернулся к предыдущей реализации, и в этой версии дополнительные вызов ProcessAllCubeDataOfUpcommingChunk не происходит. Это говорит о том, что проблема может заключаться не в самом действии onIsBorderCube, а в другом месте кода.
  • Я рассмотрел все ссылки на < strong>ProcessAllCubeDataOfUpcommingChunk и подтвердил, что его следует вызывать только один раз в соответствующем скрипте.
  • Во время отладки я заметил, что когда метод вызывается в этот дополнительный раз, отладчик не возвращается к месту, где был вызван ProcessAllCubeDataOfUpcommingChunk.
  • Я также проверил стек вызовов на наличие действительных и недопустимых итераций вызова этого метода. Как ни странно, стеки вызовов выглядят одинаково в обоих случаях, несмотря на то, что один из них приводит к дополнительному вызову.
Действительно итерация
введите здесь описание изображения
Неверная итерация
введите здесь описание изображения
Я предполагаю, что это может происходить из-за порядка выполнения функций событий, но пытаюсь найти причину.
Здесь я отправляю видео, как это выглядит, когда я занимаюсь устранением проблемы.

Подробнее здесь: https://stackoverflow.com/questions/791 ... ty-c-sharp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»