捕捉到y轴Unity中存储的相对旋转

时间:2018-06-14 16:38:01

标签: c# unity3d hololens

这适用于在Unity中开发的Microsoft HoloLens应用程序。

我正在开发一个功能,即#34; save"用户能够轻松返回的观点。我这样做是通过将场景中对象的相对位置/方向存储到主摄像机,然后通过语音命令将对象恢复到之前的相对位置/方向。

我的位置恢复工作正常,我只需要恢复偏航轴(y)的方向,以便用户面对正确的方向。

我尝试使用此解决方案将场景对象的相对 y方向(在本例中称为" terrainContainer")恢复到主摄像头:

//this is the stored relative orientation in y
float deltaYaw = Camera.main.transform.rotation.eulerAngles.y - terrainContainer.transform.rotation.eulerAngles.y; 

//this function adjusts the orientation of the terrainContainer to match previous relative orientation that was stored
public void SwitchRelativeOrientation(float deltaYaw, GameObject terrainContainer){
     float curDeltaYaw = Camera.main.transform.rotation.eulerAngles.y - terrainContainer.transform.rotation.eulerAngles.y;
     float diffDeltas = curDeltaYaw - deltaYaw;
     float setYaw = terrainContainer.transform.rotation.eulerAngles.y + diffDeltas;
     setYaw = Utils.MathUtils.Normalise(setYaw, 0, 360); //normalises the value recovered to a range from [0,360]

     //adjusting terrainContainer rotation
     terrainContainer.transform.rotation = Quaternion.Euler(terrainContainer.transform.rotation.x, setYaw, terrainContainer.transform.rotation.z);
}

当我执行以下操作时,此实现有效:

  • 保存我的观点
  • 在主位置和方向上移动主相机(通过HoloLens中的头部移动)
  • 将地形移动到位,但不是方向
  • 恢复到视点

当我执行以下操作时,此实现失败

  • 保存我的观点
  • 将地形的方向重置为0度
  • 向任意方向旋转地形
  • 恢复到视点

当发生故障时,方向取决于地形旋转的程度。因此,如果地形被用户逆时针旋转20度,地形应该是50度,那么地形最终会达到70度。

我无法弄清楚为什么会这样。我在轮换前做轮换。我很感激您提供的任何帮助!

编辑: 正如下面的评论中提到的,我采用了一种稍微不同的方法来解决这个最终起作用的问题:

//this is the stored relative orientation in y
float deltaYaw = viewpoint.transform.localRotation.eulerAngles.y

//this function adjusts the orientation of the terrainContainer to match previous relative orientation that was stored
public void SwitchRelativeOrientation(float deltaYaw, GameObject terrainContainer){
     Quaternion toQuat = Camera.main.transform.localRotation;
    //my implementation is flat on the xz plane
     toQuat.eulerAngles = new Vector3(0, toQuater.eulerAngles.y, 0);
    //orient terrain to same as camera
    terrainContainer.transform.rotation = toQuat;
    //now add the previous difference in rotation to the terrain
    terrainContainer.transform.rotation = Quaternion.Euler(terrainContainer.transform.rotation.eulerAngles.x, terrainContainer.transform.rotation.eulerAngles.x + deltaYaw, terrainContainer.transform.rotation.eulerAngles.z);
}

2 个答案:

答案 0 :(得分:0)

但我还可以提出另一个问题

terrainContainer.transform.rotation = Quaternion.Euler(terrainContainer.transform.rotation.x, setYaw, terrainContainer.transform.rotation.z);

旋转是一个四元数,它本质上是一个Vector4,你可以通过rot.x,rot.y,rot.z,rot.w寻址它的成员,但那些与欧拉角不同,那些部分是弥补四元数。试试yhid:

    terrainContainer.transform.rotation = Quaternion.Euler(terrainContainer.transform.eulerAngles.x, setYaw, terrainContainer.eulerAngles.z);

同样通过

setYaw = Utils.MathUtils.Normalise(setYaw, 0, 360);

如果你的setYaw大于360(在某些情况下可能是这样),你将截断信息。 您可以简单地删除此行,因为Unity的角度大于360,或者如果您确实需要截断值,则可以执行此操作

setYaw = setYaw % 360; //modulo division

答案 1 :(得分:0)

正如下面的评论中提到的,我采用了一种稍微不同的方法来解决这个最终有效的问题:

//this is the stored relative orientation in y
float deltaYaw = viewpoint.transform.localRotation.eulerAngles.y

//this function adjusts the orientation of the terrainContainer to match previous relative orientation that was stored
public void SwitchRelativeOrientation(float deltaYaw, GameObject terrainContainer){
     Quaternion toQuat = Camera.main.transform.localRotation;
    //my implementation is flat on the xz plane
     toQuat.eulerAngles = new Vector3(0, toQuater.eulerAngles.y, 0);
    //orient terrain to same as camera
    terrainContainer.transform.rotation = toQuat;
    //now add the previous difference in rotation to the terrain
    terrainContainer.transform.rotation = Quaternion.Euler(terrainContainer.transform.rotation.eulerAngles.x, terrainContainer.transform.rotation.eulerAngles.x + deltaYaw, terrainContainer.transform.rotation.eulerAngles.z);
}