Каждый кватернион, создаваемый LookRotation
, таков, что вращается от единичного вращения до вращения, указанного параметрами. Применение второго поворота из неидентичного поворота (что и делает q1 * q2
) может привести к тому, что он не будет соответствовать одному или обоим из LookRotation
параметров, с которыми q2
был создан.
Используйте Vector3.OrthoNormalize
, чтобы найти вектор, ортогональный normal
, ближайший к target.position - transform.position
. Вам придется справиться с ситуацией, когда нормальное и это направление параллельны.
Затем используйте Quaternion.LookRotation
, чтобы получить вращение, которое укажет forward
и up
преобразования в следующих направлениях:
Vector lookDirection = target.position - transform.position;
if (Mathf.Approximately(1f, Vector3.Dot(normal, lookDirection)))
{
// normal and lookDirection are parallel
// Do something reasonable about look direction here.
// That may mean doing nothing at all!
return;
}
Vector3.OrthoNormalize(ref normal, ref lookDirection);
Quaternion newRotation = Quaternion.LookRotation(lookDirection, normal);
Rigidbody.MoveRotation(newRotation);
Альтернативой является использование LookRotation
, чтобы смотреть в направлении normal
и располагаться как можно ближе к направлению от цели, вначале, насколько это возможно, затем наклон вниз на 90 градусов:
Vector lookDirection = target.position - transform.position;
if (Mathf.Approximately(1f, Vector3.Dot(normal, lookDirection)))
{
// normal and lookDirection are parallel
// Do something reasonable about look direction here.
// That may mean doing nothing at all!
return;
}
Quaternion bottomTowardsTarget = Quaternion.LookRotation(normal, -lookDirection);
Quaternion newRotation = bottomTowardsTarget * Quaternion.Euler(-90f,0,0);
Rigidbody.MoveRotation(newRotation);