Вы можете определить кватернион, который будет вращать судно на воздушной подушке от его текущего до мирового уровня, используя Quaternion.FromToRotation
:
Rigidbody hoverRB; // hovercraft's rigidbody
Quaternion deltaQuat = Quaternion.FromToRotation(hoverRB.transform.up, Vector3.up);
Затем используйте Quaternion.ToAngleAxis
чтобы преобразовать это в угол и ось:
Vector3 axis;
float angle
deltaQuat.ToAngleAxis(out angle, out axis);
Затем отмените некоторые из существующих вращений, чтобы в итоге достичь цели:
float dampenFactor = 0.8f; // this value requires tuning
hoverRB.AddTorque(-hoverRB.angularVelocity * dampenFactor, ForceMode.Acceleration);
И затем применитенекоторый крутящий момент вдоль оси, которую мы нашли ранее, в зависимости от остаточного угла:
float adjustFactor = 0.5f; // this value requires tuning
hoverRB.AddTorque(axis.normalized * angle * adjustFactor, ForceMode.Acceleration);
Любое преобразование между радианами, используемыми твердотельным телом и степенями ToAngleAxis
, избыточно с константами float
, поэтому не надослишком беспокоиться об этом.
Убедитесь, что все это делается в FixedUpdate
(или функции, вызываемой / работающей во время FixedUpdate
) из-за того, что направление крутящего момента, вероятно, должно будет измениться от одной физикишаг к другому. Итак, всего:
Rigidbody hoverRB; // hovercraft's rigidbody
...
void FixedUpdate()
{
Quaternion deltaQuat = Quaternion.FromToRotation(hoverRB.transform.up, Vector3.up);
Vector3 axis;
float angle
deltaQuat.ToAngleAxis(out angle, out axis);
float dampenFactor = 0.8f; // this value requires tuning
hoverRB.AddTorque(-hoverRB.angularVelocity * dampenFactor, ForceMode.Acceleration);
float adjustFactor = 0.5f; // this value requires tuning
hoverRB.AddTorque(axis.normalized * angle * adjustFactor, ForceMode.Acceleration);
}