向鼠标旋转

时间:2017-05-31 21:43:57

标签: c# unity3d rotation

我想将一个立方体朝着鼠标位置(在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;`

为了得到真正的情感?

1 个答案:

答案 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

的条件的影响