Хорошо, тогда давайте еще раз попробуем. Существует две основные фазы обнаружения столкновений в любой эффективной системе. Есть широкая и узкая фаза, если хотите. Широкая фаза использует неточные, но дешевые методы, чтобы определить, могут ли два объекта пересекаться, и передать их в узкую фазу. Узкая фаза принимает два наших объекта-кандидата и применяет более сложную физику для опосредования столкновения.
В мире сеток у нас есть очень простой и выгодный метод для широкофазного столкновения. Это сама сетка. Мы можем использовать позицию и размер игрока, чтобы определить 8 блоков, которые он может пересекать (теперь мы будем использовать ваш случай). Обратите внимание, что в моем первоначальном ответе мне показалось, что я говорил о том, чтобы сузить его до 3 блоков - я делал его более сложным, чем нужно, особенно для символа с 1 блоком. Самый простой способ заключается в следующем: округлите центр вашего персонажа до угла сетки, то есть там, где пересекаются углы 8 блоков. Затем выберите эти 8 блоков для узкофазного тестирования. Обязательно используйте округление средней точки , а не округление по полу, как это используется по умолчанию при работе с целыми числами. То есть, если значение равно 1,53, оно должно округляться до 2, а 1,49999 - до 1.
Теперь, узкая фаза, которую я на самом деле не очень много охватываю. Вы спросили, стоит ли двигаться первым или после, я думаю, что вам нужно сначала сделать это. Я не мастер симуляции физики, но я знаю, что вы сначала хотите рассчитать направление столкновения (центр персонажа минус центр блока). Глубина - это длина этого вектора. Если ваши блоки имеют ширину 1, то вы не хотите, чтобы эта длина была меньше 1; это показывает, что они пересекаются (в некоторой степени в основном).
Теперь есть много способов «восстановить» объекты после столкновения. Я бы предложил определить, по какой оси объекты сталкиваются меньше . То есть, если компонент X вашего вектора направления столкновения является наименьшим, это означает, что ваш игрок находится ближе всего к из столкновения в направлении X. Приложите противодействующую силу в этом направлении, пропорциональную глубине столкновения в направлении X. Или, если вы выберете, просто установите положение вашего персонажа на расстояние, которое вы хотите убрать, и не напрягайтесь силами. Но вы хотите перемещать персонажа только в одном кардинальном направлении. Это делает вещи проще и не мешает движению вдоль земли или вдоль стен.
Подумайте об этом так: скажем, каждый кадр вашего персонажа падает .3 в землю под действием силы тяжести. Теперь предположим, что он находится в центре блока, когда он попадает в этот кадр. Это означает, что его глубина столкновения с блоком под ним составляет (0,5, 0,3, 0,5) (где X в боковом направлении, Y в верхнем положении, а Z в прямом направлении). Если вы примените восстанавливающую силу во всех этих направлениях, вы будете перемещать игрока влево, назад и назад по земле. Этот последний бит - единственная часть, которую вы хотели сделать. Поэтому игнорируйте большие оси столкновения и восстанавливайте только по меньшей (Y). Теперь горизонтальное движение вашего персонажа беспрепятственно, и он остается над землей.