Я работаю над 2D-игрой в плоскости XY. Я создал врагов с помощью NavMeshAgent и дал своим агентам возможность перемещаться между ними. Проблема в том, что я не знаю, как вращать их в направлении движения или векторе скорости (синяя стрелка). Передняя часть агента находится в направлении оси Y (зеленая стрелка). Обратите внимание, что updateRotation не является опцией. Он повернет агент и заставит его исчезнуть (агент вращается на 90 градусов вокруг оси X).
вот код, который я нашел на форуме Unity, он отлично работает в 3D, но я не могу заставить его работать в 2D
void FaceTarget()
{
Vector3 direction = agent.steeringTarget;
Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5);
}
Я попробовал этот код. Он вычисляет угол между вектором скорости и локальной осью Y. Желаемый результат: агент вращается в направлении своего движения. На самом деле агент вращается, но в некоторых моментах он не в направлении движения. Я знаю, что проблема в том, что диапазон ангелов составляет [0,180], а не [0,360], но я не могу найти для этого решения.
void FaceTarget()
{
Vector3 lookTarget = agent.velocity.normalized;
float angel = Vector3.Angle(lookTarget, Vector3.up);
transform.rotation = Quaternion.Euler(0,0,angel);
}





ОБНОВЛЕНИЕ: Изменено для работы с 2D-плоскостью x-y, в то время как оригинал был 2-мерной плоскостью в 3d-x-z.
SteeringTarget не эквивалентен вектору направления. Это положение целевого вектора, к которому нужно добраться. Желаемое направление больше похоже на SteeringTarget — текущую позицию агента.
Фактическое направление движения можно получить из Agent.velocity.
Ваш код выше можно изменить на:
void FaceTarget()
{
Vector3 direction = agent.velocity;
Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, direction.y, 0));
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5);
}
Однако одна из проблем заключается в том, что на низких скоростях видимое вращение будет происходить резко и, казалось бы, случайно. Чтобы этого не произошло, рассмотрите возможность применения порога скорости к вращению, как показано ниже:
void FaceTarget()
{
if (agent.velocity.magnitude > MINIMUM_SPEED)
{
Vector3 direction = agent.velocity;
Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, direction.y, 0));
transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5);
}
}
Наконец, если у вас возникнут какие-либо проблемы, рассмотрите возможность поворота подобъекта, предназначенного только для визуальных эффектов, вместо основного преобразования.
Quaternion.LookRotation неявно использует Vector3.up (0,1,0) в качестве вектора вверх, который работает в трехмерном пространстве. Попробуйте использовать Vector3.forward (0,0,1) или Vector3.back (0,0,-1) в качестве вектора вверх и посмотрите, что получится. Это должно привести к вращению во 2d горизонтальной плоскости. Это может выглядеть так: Quaternion.LookRotation(new Vector3(direction.x, Direction.y, 0), Vector3.forward);
Спасибо за ответ, мне очень помогло🙏
Я решил это с помощью Вот код
void FaceTarget()
{
if (agent.velocity != Vector3.zero)
{
Vector3 moveDirection = new Vector3(agent.velocity.x, agent.velocity.y, 0f);
if (moveDirection != Vector3.zero)
{
float angel = Mathf.Atan2(moveDirection.x, moveDirection.y) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angel, Vector3.back);
}
}
}
Вот еще один код, предоставленный @DMGregory
void FaceTarget() {
var vel = agent.velocity;
vel.z = 0;
if (vel != Vector3.zero)
{
transform.rotation = Quaternion.LookRotation(Vector3.forward, vel);
}
}
Для низких скоростей я обычно использую .Normalized, чтобы получить направление вектора. Я попробовал код, который вы предоставили. Он вращает поверхность агентов в направлении вектора скорости. Другая проблема заключается в том, что при остановке агента все возвращается в нормальное состояние. Я имею в виду, что агент возвращается к ротации (0,0,0). Методы кватернионов, которые обычно используются в 3D, в этом случае не могут быть использованы. Все они используют ось Z в качестве прямого вектора.