我想将一个立方体朝着鼠标位置(在2d中)以单位(c#)旋转。我有这个代码,但我不工作:
Vector3 a = GameObject.FindGameObjectWithTag("GunTop").transform.position;
Vector3 b = GameObject.FindGameObjectWithTag("GunBottom").transform.position;
Vector3 c = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.x);
float aTob = Vector3.Distance(GameObject.FindGameObjectWithTag("GunTop").transform.position, GameObject.FindGameObjectWithTag("GunBottom").transform.position);
float aToc = Vector3.Distance(GameObject.FindGameObjectWithTag("GunTop").transform.position, new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.x));
float bToc = Vector3.Distance(GameObject.FindGameObjectWithTag("GunBottom").transform.position, new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.x));
float winkel = Mathf.Acos(((Vector3.Distance(GameObject.FindGameObjectWithTag("GunTop").transform.position, GameObject.FindGameObjectWithTag("GunBottom").transform.position) * Vector3.Distance(GameObject.FindGameObjectWithTag("GunTop").transform.position, GameObject.FindGameObjectWithTag("GunBottom").transform.position)) + (Vector3.Distance(GameObject.FindGameObjectWithTag("GunBottom").transform.position, new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.x)) * Vector3.Distance(GameObject.FindGameObjectWithTag("GunBottom").transform.position, new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.x))) - (Vector3.Distance(GameObject.FindGameObjectWithTag("GunTop").transform.position, new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.x)) * Vector3.Distance(GameObject.FindGameObjectWithTag("GunTop").transform.position, new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.x)))) / (2 * Vector3.Distance(GameObject.FindGameObjectWithTag("GunTop").transform.position, GameObject.FindGameObjectWithTag("GunBottom").transform.position) * Vector3.Distance(GameObject.FindGameObjectWithTag("GunBottom").transform.position, new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.x))));
private void Update()
{
transform.Rotate(0, 0, winkel);
}
GunTop和GunBottom是立方体中间最高点,用鼠标创建一个三角形。有人看到问题吗?
EDIT1: 好的,好消息。现在我必须解决问题。第一个像memBrain sad(我改了一下):
` private void Update()
{
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 dir = Input.mousePosition - pos;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, 0, angle - 90);
}`
我必须改变它才能与团结一致。第二个解决方案,我可以优化我的代码,所以它现在可以工作:
` float winkel;
float echterWinkel;
float aTob;
float aToc;
float bToc;
private void Update()
{
Vector3 a =
GameObject.FindGameObjectWithTag("GunTop").transform.position;
Vector3 b =
GameObject.FindGameObjectWithTag("GunBottom").transform.position;
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 dir = Input.mousePosition - pos;
aTob = Vector3.Distance(a, b);
aToc = Vector3.Distance(a, dir);
bToc = Vector3.Distance(b, dir);
winkel = Mathf.Acos(((aTob * aTob) + (bToc * bToc) - (aToc * aToc)) / (2
* aTob * bToc));
echterWinkel = Mathf.Rad2Deg * winkel;
if (dir.x < 0)
{
transform.rotation = Quaternion.Euler(0, 0, echterWinkel);
}
else
{
transform.rotation = Quaternion.Euler(0, 0, -echterWinkel);
}
}
}`
好的,到目前为止一切顺利。但我现在要提问。显然第一个解决方案是更好的解决方案,所以我想知道它是如何工作的,“Mathf.Atan2()”是什么?
现在秒问题:为什么我必须这样做
`Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 dir = Input.mousePosition - pos;`
为了得到真正的情感?
答案 0 :(得分:1)
你的代码对我来说似乎不必要了。你需要所有这些载体吗?尽管如此,以下代码是Unity论坛(http://answers.unity3d.com/questions/731922/rotate-object-to-face-mouse-2d-rotate-on-z-axis.html)中的一个示例,您可以使用它来围绕z轴旋转对象。
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 dir = Input.mousePosition - pos;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
这真的很简单。
编辑:请记住,转换将是目标GameObject的转换。
另外,您的示例中的无效代码效率很低。您已声明了不使用的向量,并且您不使用浮动。因此,您可以使用这些存储的值替换大量代码。
Vector3 a = GameObject.FindGameObjectWithTag("GunTop").transform.position;
Vector3 b = GameObject.FindGameObjectWithTag("GunBottom").transform.position;
Vector3 c = new Vector3 (
Input.mousePosition.x,
Input.mousePosition.y,
Input.mousePosition.x
);
float aTob = Vector3.Distance(a, b);
float aToc = Vector3.Distance(a, c);
float bToc = Vector3.Distance(b, c);
float winkel = Mathf.Acos (
(
(
aTob * aTob
) +
(
bToc * bToc
) -
(
aToc * aToc
)
) /
(
2 * aTob * bToc
)
);
private void Update()
{
transform.Rotate(0, 0, winkel);
}
请注意,正确使用存储的值后代码现在看起来有多简单。我也冒昧地使用像花括号一样的括号来使长行代码更具可读性。你需要记住一件事。查找可能很昂贵。如果不需要,不要多次查找。
我没有费心检查代码是否正确。我甚至无法验证您的查找是否会返回值。实际上,这可能会成为此代码的问题。如果任一查找失败,您将在a或b或两者中存储空值!您需要某种条件检查来验证a和b是否有成功的查找,以及如果他们没有,该怎么办。就目前而言,当您第一次使用a或b时尝试对其执行操作时,您将失败。目标是优雅而不是有力地失败。
编辑2:再次查看所有内容,我注意到另一个问题。您的目的是围绕z轴旋转,并将z坐标设置为Input.mousePosition.x。这是错的。您应该将其设置为固定值,如“0”。你不希望z绑定到x。
编辑3:Here is the information provided by the Unity Scripting API for Mathf.Atan2(...)。
是。这两行与获得鼠标位置有关。让我解释一下这里发生了什么。
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
此行将“gun”对象的世界坐标(transform.position)转换为屏幕点坐标,并将其存储在pos中。
Vector3 dir = Input.mousePosition - pos;
该行获取mousePosition向量并从中减去之前的位置向量(pos),并将其存储在dir中(大概是“方向”)。您可以像下面一样轻松更改Vector3 c:
Vector3 c = Input.mousePosition;
这相当于你所做的,而不需要像你一样明确地为它创建新的Vector3并为其指定矢量坐标。
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
这一行取代了winkel。因此,您的整个代码可以压缩如下:
GameObject gun;
void Start()
{
/*
initialization code for gun GameObject
*/
}
void Update()
{
Vector3 gunScreenPosition = Camera.main.WorldToScreenPoint(gun.transform.position);
Vector3 mouseDirection = Input.mousePosition - gunScreenPosition;
float angle = Mathf.Atan2(mouseDirection.y, mouseDirection.x) * Mathf.Rad2Deg;
gun.transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
}
您真的不需要您使用的所有额外代码。你需要GunTop和GunBottom吗?如果只是计算枪的位置,我的例子就是你所需要的。
如果我不再分享一件事,我会失职的。使用Quaternion.Euler(...)时要小心。它可能会受到称为“gimbal lock”的条件的影响