#unity3d #physics #velocity
Вопрос:
Я пытаюсь сделать механика подбора предметов, как в Амнезии. Легко рассчитать необходимую скорость твердого тела, чтобы удерживаемый объект оставался перед камерой, но моя проблема в том, что объект вообще не вращается, когда я его держу. И я бы предпочел, чтобы он всегда был повернут в сторону камеры. Этого можно легко достичь, просто поместив объект в камеру игрока, но…
Поведение, которого я добиваюсь, заключается в следующем: если бы бутылка, которую я взял, стояла на столе, горлышко бутылки было обращено к потолку, я бы хотел, чтобы эта бутылка всегда была обращена горлышком к потолку, пока я ее держу. Но если эта бутылка столкнется с чем-то, она должна вести себя так, как будто она на самом деле на что-то наткнулась, поэтому она должна немного вращаться, но всегда должна пытаться вернуться к своему «первоначальному» вращению (в данном случае горлышко обращено к потолку).
Я думаю, что для этого мне нужно рассчитать угловую скорость, и, вероятно, у меня есть немного lerp, чтобы вернуться к исходному вращению, но я не знаю, как это правильно сделать.
Я думаю, что первое, что мне нужно будет сделать, это сохранить начальное направление в тот момент, когда игрок поднимет объект:
Vector3 targetDirection = playerCamera.transform.position - transform.position;
Скрипт находится на удерживаемом объекте, поэтому «преобразование» относится к нему. В FixedUpdate() мне, вероятно, потребуется некоторая интерполяция, чтобы угловая скорость всегда пыталась повернуть объект к исходному вращению:
rigidbody.angularVelocity = Vector3.Lerp(rigidbody.angularVelocity, targetAngularVelocity, lerpSpeed * Time.fixedDeltaTime);
Я не знаю, как рассчитать targetAngularVelocity, потому что, в конце концов, я бы хотел, чтобы удерживаемый объект плавно возвращался к исходному вращению. Я даже не уверен, что это правильный способ сделать это, и, возможно, мне следует сделать что-то другое, кроме расчета угловой скорости, необходимой для правильного вращения объекта. Я попытался просто интерполировать локальное вращение в исходное локальное вращение, но это не позволило удерживаемому объекту наткнуться на что-то (движение тогда было очень нервным). Есть какие-нибудь идеи?
Комментарии:
1. Является ли простое использование
rigidbody.MoveRotation
не вариантом?2. Как я уже сказал, возможно, для этого мне не нужно вычислять угловую скорость. Я мог бы использовать MoveRotation(), но все же я не уверен, как кодировать поведение, которое я описал.
Ответ №1:
Тебе нужен стабилизатор. Сценарий, который добавит крутящий момент/угловую скорость объекту, угол наклона которого отличается от целевого. Скажем, у вас есть две переменные: targetDirection
и currentDirection
ака transform.forward
. Затем вы пишете что-то вроде этого в исправленном обновлении:
var rotation = Quaternion.FromToRotation(currentDirection, targetDirection).eulerAngles * sensitivity;
rigidbody.angularVelocity = rotation;
Я рекомендую установить чувствительность около 0,05, а затем увеличить ее, если объект стабилизируется слишком медленно.
Вероятно, я перепутал порядок, поэтому вам следует где-то поставить минус, но сам подход применим.
Комментарии:
1. Спасибо! Но я думаю, что это должно быть что-то другое, чем Vector3.SignedAngle (), поскольку он возвращает float, а angularVelocity-это Vector3. Возможно, вы имели в виду Vector3.Lerp()?
2. О, я отредактировал ответ
3. Похоже, мы все еще чего-то не понимаем. С Кватернионом. FromToRotation() удерживаемый объект просто постоянно вращается, никогда не достигая своего первоначального вращения. Я попытался поместить разные вещи в текущее и целевое направление, например transform.forward или (PlayerCam.transform.position — преобразование.позиция), но, похоже, ничего не работает должным образом.
4. Вы имеете в виду
rotation
вместоangle
этого ?5. Ах, да. Я просто переименовал переменную, чтобы соответствовать ее значению)