这适用于在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);
}
当我执行以下操作时,此实现有效:
当我执行以下操作时,此实现失败:
当发生故障时,方向取决于地形旋转的程度。因此,如果地形被用户逆时针旋转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);
}
答案 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);
}