如何将立方体的旋转与四边形相匹配,以便在我移动它时它保持平整?
How do I match the rotation of a cube to a quad so it stays flat on it as I move it?
为简单起见,我只是尝试沿着成一定角度的四边形绘制箭头预制件。无论它处于什么位置,我都需要它平放在它上面(稍微凸起)。
我现在正在做的是为箭身准备一个立方体,为头部准备一个“三角形”预制件。我在屏幕上单击以获取“开始位置”(使用光线投射命中点以确保我在下面的旋转四边形上方),然后当我在它周围拖动鼠标时更新“结束位置”向量 3。我只需计算两点之间的距离,看看“localScale.y”将其扩展多少,这对箭头长度非常有效。对于头部,我只是将它附加到“终点”,所以它只是跟随鼠标。
我遇到的问题是它没有在四边形 上保持“平坦”,四边形在 X 处旋转了 70 度(在检查器中)。因此,当我移动并旋转鼠标时,它会围绕长度轴旋转。
这是我的代码:
if (Physics.Raycast(mouseRay, out hit))
{
arrowEndPoint = hit.point;
// Get rotation of Quad
quadRotation = rotatedQuad.transform.rotation.eulerAngles.x;
var arrowBodyRotation = simpleArrowBody.transform.rotation.eulerAngles;
var arrowHeadRotation = simpleArrowHead.transform.rotation.eulerAngles;
arrowBodyRotation.x = quadRotation; // Doesn't seem to be affecting it
arrowHeadRotation.x = quadRotation;
// Follow arrow head to mouse
simpleArrowHead.transform.position = arrowEndPoint;
// Get distance between Start and End point
arrowLength = Vector3.Distance(arrowStartPoint, arrowEndPoint);
// Direction based on the start and end points
var direction = (arrowEndPoint - arrowStartPoint).normalized;
// Adjust scale and rotation of Body
simpleArrowBody.transform.localScale = new Vector3(simpleArrowBody.transform.localScale.x, arrowLength, simpleArrowBody.transform.localScale.z);
simpleArrowBody.transform.up = direction;
// Adjust rotation of Head
simpleArrowHead.transform.up = direction;
simpleArrowHead.transform.up = -rotatedQuad.transform.forward; // Didn't work
}
quadRotation = rotatedQuad.transform.rotation.eulerAngles.x;
var arrowBodyRotation = simpleArrowBody.transform.rotation.eulerAngles;
var arrowHeadRotation = simpleArrowHead.transform.rotation.eulerAngles;
arrowBodyRotation.x = quadRotation; // Doesn't seem to be affecting it
arrowHeadRotation.x = quadRotation;
当然这个一点作用都没有!
您只是将其分配给局部变量 Vector3
(这是一个 struct
,因此是一个 复制值 )。
如果你想实际应用它,你会例如使用
quadRotation = rotatedQuad.transform.rotation.eulerAngles.x;
var arrowBodyRotation = simpleArrowBody.transform.rotation.eulerAngles;
var arrowHeadRotation = simpleArrowHead.transform.rotation.eulerAngles;
arrowBodyRotation.x = quadRotation;
arrowHeadRotation.x = quadRotation;
simpleArrowBody.transform.rotation.eulerAngles = arrowBodyRotation;
simpleArrowHead.transform.rotation.eulerAngles = arrowHeadRotation;
但是 请注意 eulerAngles
对他来说非常不可靠!
直接使用旋转通常很棘手。所以我通常更喜欢使用向量,因为我更了解它们 ;)
我会做的是
而是以一种“正常”定向的方式设计你的箭头。这意味着它指向本地 Z(向前) 方向,面向你的方向是它的本地向上方向。在这种情况下,Unity 提供了辅助方法。
然后您可以简单地将 Quaternion.LookRotation
与您的 direction
一起使用,并将向上矢量传递给 -rotatedQuad.transform.forward
例如
public class Example : MonoBehaviour
{
public Transform rotatedQuad;
public Transform simpleArrowHead;
public Transform simpleArrowBody;
private Vector3? arrowStartPoint;
private void Update()
{
var mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Input.GetMouseButtonDown(0) && Physics.Raycast(mouseRay, out var hit))
{
arrowStartPoint = hit.point;
}
else if (arrowStartPoint.HasValue && Input.GetMouseButton(0) && Physics.Raycast(mouseRay, out hit))
{
var arrowEndPoint = hit.point;
// Get distance between Start and End point
var delta = arrowEndPoint - arrowStartPoint.Value;
var arrowLength = delta.magnitude;
// Direction based on the start and end points
var direction = delta.normalized;
// Adjust position, scale and rotation of Body
var scale = simpleArrowBody.localScale;
scale.z = arrowLength;
simpleArrowBody.localScale = scale;
// make the forward point into the direction while maintaining the
// up vector aligned with the quad surface
simpleArrowBody.rotation = Quaternion.LookRotation(direction, -rotatedQuad.forward);
// place at center between start and end
simpleArrowBody.position = arrowStartPoint.Value + delta / 2f;
// Follow arrow head to mouse and adjust rotation of Head
simpleArrowHead.position = arrowEndPoint;
// make the forward point into the direction while maintaining the
// up vector aligned with the quad surface
simpleArrowHead.rotation = Quaternion.LookRotation(direction, -rotatedQuad.forward);
}
}
}
为简单起见,我只是尝试沿着成一定角度的四边形绘制箭头预制件。无论它处于什么位置,我都需要它平放在它上面(稍微凸起)。
我现在正在做的是为箭身准备一个立方体,为头部准备一个“三角形”预制件。我在屏幕上单击以获取“开始位置”(使用光线投射命中点以确保我在下面的旋转四边形上方),然后当我在它周围拖动鼠标时更新“结束位置”向量 3。我只需计算两点之间的距离,看看“localScale.y”将其扩展多少,这对箭头长度非常有效。对于头部,我只是将它附加到“终点”,所以它只是跟随鼠标。
我遇到的问题是它没有在四边形 上保持“平坦”,四边形在 X 处旋转了 70 度(在检查器中)。因此,当我移动并旋转鼠标时,它会围绕长度轴旋转。
这是我的代码:
if (Physics.Raycast(mouseRay, out hit))
{
arrowEndPoint = hit.point;
// Get rotation of Quad
quadRotation = rotatedQuad.transform.rotation.eulerAngles.x;
var arrowBodyRotation = simpleArrowBody.transform.rotation.eulerAngles;
var arrowHeadRotation = simpleArrowHead.transform.rotation.eulerAngles;
arrowBodyRotation.x = quadRotation; // Doesn't seem to be affecting it
arrowHeadRotation.x = quadRotation;
// Follow arrow head to mouse
simpleArrowHead.transform.position = arrowEndPoint;
// Get distance between Start and End point
arrowLength = Vector3.Distance(arrowStartPoint, arrowEndPoint);
// Direction based on the start and end points
var direction = (arrowEndPoint - arrowStartPoint).normalized;
// Adjust scale and rotation of Body
simpleArrowBody.transform.localScale = new Vector3(simpleArrowBody.transform.localScale.x, arrowLength, simpleArrowBody.transform.localScale.z);
simpleArrowBody.transform.up = direction;
// Adjust rotation of Head
simpleArrowHead.transform.up = direction;
simpleArrowHead.transform.up = -rotatedQuad.transform.forward; // Didn't work
}
quadRotation = rotatedQuad.transform.rotation.eulerAngles.x; var arrowBodyRotation = simpleArrowBody.transform.rotation.eulerAngles; var arrowHeadRotation = simpleArrowHead.transform.rotation.eulerAngles; arrowBodyRotation.x = quadRotation; // Doesn't seem to be affecting it arrowHeadRotation.x = quadRotation;
当然这个一点作用都没有!
您只是将其分配给局部变量 Vector3
(这是一个 struct
,因此是一个 复制值 )。
如果你想实际应用它,你会例如使用
quadRotation = rotatedQuad.transform.rotation.eulerAngles.x;
var arrowBodyRotation = simpleArrowBody.transform.rotation.eulerAngles;
var arrowHeadRotation = simpleArrowHead.transform.rotation.eulerAngles;
arrowBodyRotation.x = quadRotation;
arrowHeadRotation.x = quadRotation;
simpleArrowBody.transform.rotation.eulerAngles = arrowBodyRotation;
simpleArrowHead.transform.rotation.eulerAngles = arrowHeadRotation;
但是 请注意 eulerAngles
对他来说非常不可靠!
直接使用旋转通常很棘手。所以我通常更喜欢使用向量,因为我更了解它们 ;)
我会做的是
而是以一种“正常”定向的方式设计你的箭头。这意味着它指向本地 Z(向前) 方向,面向你的方向是它的本地向上方向。在这种情况下,Unity 提供了辅助方法。
然后您可以简单地将
Quaternion.LookRotation
与您的direction
一起使用,并将向上矢量传递给-rotatedQuad.transform.forward
例如
public class Example : MonoBehaviour
{
public Transform rotatedQuad;
public Transform simpleArrowHead;
public Transform simpleArrowBody;
private Vector3? arrowStartPoint;
private void Update()
{
var mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Input.GetMouseButtonDown(0) && Physics.Raycast(mouseRay, out var hit))
{
arrowStartPoint = hit.point;
}
else if (arrowStartPoint.HasValue && Input.GetMouseButton(0) && Physics.Raycast(mouseRay, out hit))
{
var arrowEndPoint = hit.point;
// Get distance between Start and End point
var delta = arrowEndPoint - arrowStartPoint.Value;
var arrowLength = delta.magnitude;
// Direction based on the start and end points
var direction = delta.normalized;
// Adjust position, scale and rotation of Body
var scale = simpleArrowBody.localScale;
scale.z = arrowLength;
simpleArrowBody.localScale = scale;
// make the forward point into the direction while maintaining the
// up vector aligned with the quad surface
simpleArrowBody.rotation = Quaternion.LookRotation(direction, -rotatedQuad.forward);
// place at center between start and end
simpleArrowBody.position = arrowStartPoint.Value + delta / 2f;
// Follow arrow head to mouse and adjust rotation of Head
simpleArrowHead.position = arrowEndPoint;
// make the forward point into the direction while maintaining the
// up vector aligned with the quad surface
simpleArrowHead.rotation = Quaternion.LookRotation(direction, -rotatedQuad.forward);
}
}
}