繁体   English   中英

通过角度差异创建 Vector3 position

[英]Create a Vector3 position by angle differences

我有一个播放器 position ,一个指示播放器视图方向距离以及水平垂直角度的指针。 我想计算一个目标 position

  • 那是远离玩家的距离position
  • 那,从玩家的角度来看,是向右的水平角度和向上的垂直角度

它是关于将 Hololens 应用程序 UI 定位在玩家周围的球体中。 用户界面应该是 40 度向左和 20 度从玩家的视角方向。

编辑:添加图像以澄清。 给出的是玩家位置 (pX|pY|pZ)、半径(= 黑色粗线的长度)和两个角度(以度为单位)。

我正在寻找如何计算 UI 中心 position (x?|y?|z?)。

在此处输入图像描述

您可以使用Quaternion.Euler根据世界空间中的角度创建旋转,然后通过将其乘以已知位置来获得所需的结果。

因此,通过使用示例,您可以找到以下位置:

float radius, x_rot, y_rot;
Vector3 forwardDirection, playerPos;

Vector3 forwardPosition = playerPos + (forwardDirection * radius);
Vector3 targetPosition = Quaternion.Euler(x_rot, y_rot, 0) * forwardPosition;

尝试查看有关QuaternionQuaternion.AngleAxis的文档,以获取更多方便的旋转内容。

// Set UI in front of player with the same orientation as the player
ui.transform.position = player.transform.position + player.transform.forward * desiredDistance;
ui.transform.rotation = player.transform.rotation;

// turn it to the left on the players up vector around the the player
ui.transform.RotateAround(player.transform.position, player.transform.up, -40);

// Turn it up on the UI's right vector around the player
ui.transform.RotateAround(player.transform.position, ui.transform.right, 20);

假设您还希望UI面对播放器,否则必须在此之后设置另一个旋转角度。

无需自己计算,Unity API已经为您完成了它(请参阅旋转

如果我正确地理解了您,那么您想创建一个悬停在某个点之上的UI。 我最近在游戏中做了类似的事情。 这就是我的做法。

 if (Input.GetMouseButtonDown(0)) // use the ray cast to get a vector3 of the location your ui      
                                 // you could also do this manualy of have the computer do it the main thing is to 
                                  // get the location in the world where you want your ui to be and the
                                 // WorldTOScreenPoint() will do the rest
        {
            RaycastHit hit;
            Vector3 pos;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray, out hit))
            {
                pos = hit.point;
                pos.y += yOffset; // use the offset if you want to have it hover above the point
                ui.transform.position = cam.WorldToScreenPoint(pos); // use your main cammera here              
                // then either make your ui vissible or instanciati it here and make sure if you instanciate it 
                // that you make it a child of your cnavas


            }
        }

我希望这可以解决您的问题。 如果我不明白您要做什么,请告诉我,我会尽力提供帮助。

注意:如果要使ui在远离点时看起来更远,则将ui随距离越远而缩小,并在距离近时将其放大。

数学家的回答:

要使用给定的信息(物体之间的距离,x角,y角)计算球形位置,请使用三角函数:

float x = distance * Mathf.Cos(yAngle) * Mathf.Sin(xAngle);
float z = distance * Mathf.Cos(yAngle) * Mathf.Cos(xAngle);
float y = distance * Mathf.Sin(yAngle);

ui.transform.position = player.transform.position + new Vector3(x,y,z);

问题中的图表有点令人困惑:

  • 轴的方向是右手坐标系,但 Unity 使用左手坐标系。
  • 就欧拉角而言,图像中标记为“x 角”的部分实际上是 Y 角(绕 Y 轴旋转),图像中标记为“y 角”的部分实际上是 X 角(绕 X 轴)。
  • 列出的两个角度使用不同的符号约定。 Y 角(标记为“x 角”)遵循右手定则,而另一个角则不然。

乔纳斯·齐默 (Jonas Zimmer) 有一个很好的答案,它遵循图像中的约定,但我会尝试做一些不那么令人困惑的事情,并遵循更标准的数学约定。

这是 C# 中编写的一些 Unity 代码,按 YX 旋转顺序,将零角度视为向前 (+Z),并遵循 Unity 的左手惯例,Y 向上,Z 向前坐标系。 增加 Y 角度向右旋转,增加 X 角度向下旋转。

public static Vector3 Vector3FromAngleYX(float y, float x)
{
    float cosx = Mathf.Cos(x);
    return new Vector3(cosx * Mathf.Sin(y), -Mathf.Sin(x), cosx * Mathf.Cos(y));
}

此外,我发现这个问题正在寻找实现 Godot 版本,所以这里是用 GDScript 编写的 Godot Engine 版本,按 YX 旋转顺序,将零角度视为正向(-Z),并遵循 Godot 的右手惯例, Y 向上,Z 向后坐标系。 增加 Y 角度向左旋转,增加 X 角度向上旋转。

func vector3_from_angle_yx(y, x):
    var neg_cosx = -cos(x)
    return Vector3(neg_cosx * sin(y), sin(x), neg_cosx * cos(y))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM