Обновить

Логика распространения точечного источника света в моей игре - Minecraft на Unity.

public sealed class ChunkLight
    {
        private readonly Queue<Vector3Int> _lightsQueue = new();
        private readonly int[,,] _blockIds;
        private readonly byte[,,] _blockLights;

        public void SetLamp(Vector3Int position, byte lightForce)
        {
            AddLightForNeighbors(position, lightForce);
            while(_lightsQueue.Count > 0)
            {
                position = _lightsQueue.Dequeue();
                AddLightForNeighbors(position, _blockLights[position.x, position.y, position.z]);
            }
        }

        private void AddLightForNeighbors(Vector3Int position, byte lightForce)
        {
            lightForce -= 1;
            AddLight(position + Vector3Int.left, lightForce);
            AddLight(position + Vector3Int.right, lightForce);
            AddLight(position + Vector3Int.back, lightForce);
            AddLight(position + Vector3Int.forward, lightForce);
            AddLight(position + Vector3Int.down, lightForce);
            AddLight(position + Vector3Int.up, lightForce);
        }

        private void AddLight(Vector3Int position, byte lightForce)
        {
            if (_blockIds[position.x, position.y, position.z] != 0) return;

            if (lightForce <= _blockLights[position.x, position.y, position.z]) return;

            _lightsQueue.Enqueue(position);
            _blockLights[position.x, position.y, position.z] = lightForce;
        }
    }

Это упрощенный вариант кода, нет проверок на границы чанков, только чистая логика света. И представим _blockIds заполнен данными 0 и 1 (0 - нету блока, 1 - есть блок), а
_blockLights имеет значения от 0 до 15.


1. Блок света (Лампа) устанавливается в ячейку с координатами (x, y, z), а сила его света lightForce = 15.
2. Перебираю соседние ячейки: (x - 1, y, z), (x + 1, y, z), (x, y - 1, z), (x, y + 2, z), (x, y, z - 1), (x, y, z + 1).
2.1 Если в соседней ячейке есть блок, то он пропускается. И если lightForce внутри блока уже больше или равен присваиваемому lightForce, то блок пропускается.
2.2 Если блока нет, то ячейке присваивается lightForce= 14. Так же эта ячейка добавляется в очередь _lightsQueue.
3. Запускаю цикл While и также перебираю блоки внутри _lightsQueue.

Если вам интересно следить за разработкой игры и влиять на саму игру, у меня есть телеграмм канал.

Теги:
0
Комментарии1

Публикации

Ближайшие события