Я работаю над игрой, в которой игрок может подбирать предметы, используя что-то вроде луча трактора, и носить их с собой.
Привлечь объект к центру луча несложно. Но как только объект окажется достаточно близко к центру, мне нужно держать его там, пока игрок движется, с чем у меня проблемы. Я могу придумать два способа сделать это, и у обоих есть проблемы:
Обновляйте позицию объекта всякий раз, когда позиция игрока изменяется, сохраняя его в центре луча.
Обновите скорость объекта, чтобы он указывал прямо на центр луча, чем дальше, тем больше скорость.
Перемещение и вращение прекрасно работают с обоими подходами, но физика неверна, когда переносимый объект сталкивается с другими объектами:
При первом подходе физика полностью игнорируется. Носимый предмет просто отталкивает что-либо с пути. Это потому, что изменение положения должно быть сделано только как часть мировой физики, основанной на скорости.
При втором подходе физика в основном ведет себя так, как должна, но слишком остро реагирует. Проблема в том, что для того, чтобы удерживаемый объект находился в центре луча, даже когда он вращается и двигается, мне нужно использовать высокие значения скорости. Поэтому, как только переносимый объект касается другого, он получает слишком большую скорость от столкновения.
Как я могу реализовать это правильно? Мое лучшее предположение сейчас состоит в том, чтобы перейти ко второму подходу и добавить специальную обработку для переносимых объектов к мировой физике, уменьшая скорость до нормальных значений для столкновений или когда игрок прекращает нести их. Но это похоже на довольно неумелый обходной путь.
Изменить: добавление псевдокода, чтобы проиллюстрировать, как он работает прямо сейчас (это будет второй подход выше)
void attract_object(object, ticks) {
Vector distance = beam_center - object.center;
// If the object is not close to the beam center, attract it slowly
if (magnitude(distance) > 10) {
object.velocity += distance.normalized() * ticks * 0.1;
return;
}
// Here comes the part we're talking about. That magic 0.5 is just high enough
// that the object isn't lost while moving around. But it's still so high that
// other objects are repelled with way too much force.
object.velocity = distance * ticks * 0.5;
}
Из того, что я вижу, это происходит, когда переносимый объект отталкивает другой объект:
- Несущийся объект сталкивается с другим объектом
- Скорости объектов распределяются правильно, поэтому переносимый объект отталкивается от центра балки в процессе
- Приведенный выше код заставляет переносимый объект возвращаться в центр балки с такой большой скоростью, что он быстро туда возвращается
- Когда переносимый объект движется обратно к центру луча, половина его высокой скорости передается другому объекту, сильно его отталкивая. Поскольку начальная скорость переносимого объекта кажется нормальной, я могу себе представить, что шаги с 2 по 4 повторяются многократно, создавая такую высокую скорость.
Это кажется причиной. Я не могу придумать хороший способ исправить это :(