如果角色的头部已经旋转了60°,角色的身体怎么能连续旋转?

sta*_*ker 17 c# java unity-game-engine google-cardboard

经过一些实验,我将一个空的(HeadCam)作为角色的脖子.此片段允许头部同步旋转到CardboardHead/Camera.

void LateUpdate() {
    neckBone.transform.rotation = Camera.transform.rotation *  Quaternion.Euler( 0,0,-90);
    Camera.transform.position = HeadCam.transform.position;
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

当只有头部在-60°到60°的范围内旋转时,角色的手臂不应该移动,之后我想移动整个角色,手臂仍然可见.只要角色翻转180°后,角色旋转不超过180°,以下方法就能正常工作,我怎样才能实现恒定旋转?

void LateUpdate() {
    Quaternion camRot = Camera.transform.rotation * Quaternion.Euler( 0,0,-90);                 
    neckBone.transform.rotation = camRot;
    float yrot = camRot.eulerAngles.y;
    float ydelta = 0;
    if ( yrot < 300f && yrot > 180 ) {
        ydelta = yrot - 300f;
    }
    if ( yrot > 60f && yrot < 180 ) {
        ydelta = yrot - 60;
    }
    playerObj.transform.rotation =  Quaternion.Euler(0, ydelta, 0); 
    Camera.transform.position = HeadCam.transform.position;
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

用于独立测试算法的java applet:https://github.com/3dbug/blender/blob/master/HeadCamRot.java

sta*_*ker 1

最后我找到了一个解决方案:

private float bodyRot = 0F;
private float FOV = 70f;

void LateUpdate() {
    if ( neckBone != null ) {
        Quaternion camRotQ = CameraFacing.transform.rotation * Quaternion.Euler( 0,0,-90);
        neckBone.transform.rotation = camRotQ;
        float camRot = camRotQ.eulerAngles.y;

        float delta = camRot- bodyRot;
        if ( delta > 180 ) {
            delta -= 360;
        }
        if ( delta < -180 ) {
            delta += 360;
        }
        if ( Math.Abs(delta) > FOV ) {
            if ((delta > FOV || delta < -180) && delta < 180) {
                bodyRot = camRot - FOV;
            }
            delta = camRot- bodyRot;
            if ((delta < FOV || delta > 180 ) ) {
                bodyRot = camRot + FOV;
            }
        }
        playerObj.transform.rotation =  Quaternion.Euler(0, bodyRot, 0); 
        CameraFacing.transform.position = cameraMount.transform.position;
    }
}
Run Code Online (Sandbox Code Playgroud)