Snake-Eyes Posted October 11 Posted October 11 Приветствую! Делаю персонажа на основе физики (RigidBody). При упоре в стену или "наклонную поверхность" и изменении LinearVelocity персонаж начинает "дергаться". Игрался с PenetrationFactor в глобальных настройках физики, частично проблема со стеной исчезла, но с наклоном всё так же. Мне кажется вообще не нужно было трогать глобальные настройки физики и проблема где-то в скрипте (могу ошибаться). В общем если есть идеи, буду рад. Спасибо! P.S. Метод отвечающий за наклоны находится в PlayerState а вызывается в PlayerWalkState. Крайняя правая платформа имеет 90 градусов, остальные 60,45,30 (Проблема только с платформой 60 градусов, т.е с теми, угол которых выходит за пределы лимита (по дефолту = 45)). PlayerState.cs PlayerWalkState.cs
karpych11 Posted October 15 Posted October 15 Здравствуйте. Я бы рекомендовал не изменять линейную скорость напрямую, т.к. в этом случае не будут корректно учитываться воздействия других тел и сил. Попробуйте вместо этого применять импульсы. Для более детального ответа потребуется сцена с воспроизведением такой проблемы.
Snake-Eyes Posted October 16 Author Posted October 16 Переделал под импульсы. Проблема с вертикальной платформой решилась, с 60 градусной платформой - нет. Сцену прикреплю. scene.upackage
karpych11 Posted October 21 Posted October 21 Я бы изменил реализацию функции SlopeMovement. Сейчас в ней проверяются все контакты капсулы и, если хотя бы для одного выполняется проверка на ограничение, то мы движемся по склону. Но у капсулы при движении по плоскости есть контакты по центру нижней сферы, нормаль которого направлена вверх. Т.е. при переходе с плоскости на склон всегда будет выполняться проверка в этой функции. Но проверка с помощью луча по направлению движения решит эту проблему. Пускаем луч от центра верхней сферы до самого низа капсулы, а потом проверяем нормаль этого пересечения. protected bool SlopeMovement(BodyRigid bodyRigid, dvec3 moveDirection, out dvec3 currentlyDirection, double slopeLimitAngle = 45) { currentlyDirection = moveDirection; if (bodyRigid.NumContacts == 0) return false; dvec3 pos0 = Shape.TopCap + moveDirection * Shape.Radius; dvec3 pos1 = Shape.BottomCap + moveDirection * Shape.Radius + dvec3.DOWN * Shape.Radius; Object obj = World.GetIntersection(pos0, pos1, 1, intersection); if (obj == null) return false; double angle = MathLib.Acos(MathLib.Dot(intersection.Normal, dvec3.UP)); if (slopeLimitAngle < angle * MathLib.RAD2DEG) return false; currentlyDirection = moveDirection - (intersection.Normal * MathLib.Dot(moveDirection, intersection.Normal)); return true; } PlayerState.cs 1 1
Recommended Posts