#unity3d #rotation #euler-angles
#unity3d #вращение #углы Эйлера
Вопрос:
Мне нужен определенный угол в локальной системе повернутых осей. По сути, я хочу получить угол в плоскости определенной системы повернутых осей. Лучший способ объяснить это графически.
Я могу сделать это, проецируя направление от начала координат до цели в моей плоскости, а затем используя Vector3.Угол (начало координат в прямом направлении, проекционное направление в плоскости).
Есть ли способ получить это аналогичным образом, Quaternion.FromToRotation(from, to).eulerAngles;
но с углами Эйлера, относительно системы координат, которая не является мировой, а локально повернутой (та, которая представлена повернутой плоскостью на рисунке выше)?
Так что желаемый угол для поворота по локальной оси y: Quaternion.FromToRotation(from, to).localEulerAngles.y
, поскольку локальные углы Эйлера будут (0, -желаемый угол, 0), на основе этого подхода.
Или есть более прямой способ, чем тот, которым я этого добился?
Комментарии:
1. Я бы посоветовал вам немного улучшить свой вопрос, лично мне немного сложно понять, о чем именно вы спрашиваете. Если вы знаете угол и векторы, в чем проблема?
2. Спасибо за ваш комментарий и предложение. Вопрос немного сложно объяснить, я сделал все возможное. Вопрос в том, что, хотя я добиваюсь своих результатов, я просил лучшего или более прямого подхода. Поскольку
Quaternion.FromToRotation(from, to).eulerAngles
они уже существуют в unity, с системой мировых осей в качестве эталона, я спрашиваю, есть ли другое аналогичное решение для других осей, которые не являются мировыми, чтобы получить углы для этой повернутой системы (локальной) вместо системы мировых осей.3. Я объясняю проблему, с которой я столкнулся, и как я ее решил, чтобы показать, как на пути к решению я подошел к вопросу, который я задаю. Надеюсь, это имеет смысл. Дайте мне знать все, что может быть непонятно.
4. Это не проверено, но… Если я все правильно понимаю, я думаю, вы можете использовать
Transform.InverseTransformPoint
для получения локальных координат цели и использоватьQuaternion.FromToRotation
, где «от» будетtarget_direction_local
и «до» будетtarget_direction_local
сy=0
( я думаю, это создает поворот от цели к плоскости в локальной системе координат ). Затем используйтеQuaternion.eulerAngles
, чтобы получить его локальные углы. Наконец, создайте новый кватерион сQuaterinion.Euler
гдеx
ваш угол иy, z
являются углами из eulerAngles.5. большое спасибо, что нашли время, чтобы понять мой вопрос и ваш комментарий. Я знаком с
Transform.InverseTransformPoin
so, поэтому ваше предложение имеет смысл для меня. Я попробую это как можно скорее и сообщу вам, если это сработает!
Ответ №1:
Если я правильно вас понимаю, вероятно, есть много возможных путей.
Я думаю, вы могли бы, например, использовать Quaternion.ToAngleAxis
, который возвращает угол и ось вокруг и который был повернут. Затем эту ось можно преобразовать в локальное пространство вашего объекта
public Vector3 GetLocalEulerAngles(Transform obj, Vector3 vector)
{
// As you had it already, still in worldspace
var rotation = Quaternion.FromToRotation(obj.forward, vector);
rotation.ToAngleAxis(out var angle, out var axis);
// Now convert the axis from currently world space into the local space
// Afaik localAxis should already be normalized
var localAxis = obj.InverseTransformDirection(axis);
// Or make it float and only return the angle if you don't need the rest anyway
return localAxis * angle;
}
В качестве альтернативы, как уже упоминалось, я думаю, да, вы также можете просто сначала преобразовать другой вектор в локальное пространство, а затем Quaternion.FromToRotation
уже должен быть в локальном пространстве
public Vector3 GetLocalEulerAngles(Transform obj, Vector3 vector)
{
var localVector = obj.InverseTransformDirection(vector);
// Now this already is a rotation in local space
var rotation = Quaternion.FromToRotation(Vector3.forward, localVector);
return rotation.eulerAngles;
}
Комментарии:
1. Большое спасибо за ваш ответ. Я попробую это и дам вам знать!!
2. Вы это сделали. Оба примера работают. Большое вам спасибо за то, что нашли время, чтобы ответить на вопрос и предоставить 2 подхода. Хотя я знал, как это сделать, эти два способа намного проще, и мое понимание поворотов улучшается.
3. Однако я не понимаю, почему во втором примере
var rotation = Quaternion.FromToRotation(Vector3.forward, localVector);
это вращение в локальном пространстве, поскольку localVector находится в локальном пространстве, ноVector3.forward
является мировым форвардом. он работает сVector3.forward
углом, который мне нужен, и дает нужный угол, но я бы сказал, что этоobj.forward
имело бы больше смысла или, по крайней мере, я бы попробовалobj.forward
раньшеVector3.forward
. Вы понимаете мою точку зрения?4. О, я понял. Оба вектора должны находиться в одном и том же пространстве. World’s.forward в локальном пространстве не (0,0,1), так же, как obj.forward — это не 0,0,1 в пространстве миров, а разложение по оси миров. Итак, в локальном пространстве Vector3.forward = 0,0,1 — это вектор, от которого мне нужно отклониться, чтобы достичь желаемого угла. На самом деле я ввел obj.forwar и вектор как в мировом пространстве, так и в ожидаемом режиме. Это так удивительно! большое спасибо!
5. @rustyBucketBay да, вы это уже поняли!;) Мне особенно нравится, что это также помогло вам понять это самостоятельно. В моих глазах это то, чем является (должна быть) эта страница в основном — помочь вам понять, а не просто предоставить готовый к использованию фрагмент кода. Так что очень рад помочь!