简体   繁体   English

轮流走向最后的轮换挑战

[英]Rotating towards a final rotation challenge

Consider this working script, that handles a FPS camera movement:考虑这个处理 FPS 摄像机移动的工作脚本:

using UnityEngine;

public class CameraHandler : MonoBehaviour {
    public Transform target;
    float dragSpeed = 10f;
    float lookAtSensitivity = 200f;
    float xRot;
    Transform parentGO;

    private void Start() {
        parentGO = transform.parent;
    }
    void goToPivot(Transform pivot) {
        parentGO.position = Vector3.Lerp(transform.position, pivot.position, 0.05f);
        transform.rotation = Quaternion.Lerp(transform.rotation, pivot.rotation, 0.05f);
    }

    void resetCamRot() {
        xRot = 0;
        float yRot = transform.localEulerAngles.y;
        parentGO.transform.eulerAngles += new Vector3(0, yRot, 0);
        transform.localEulerAngles -= new Vector3(0, yRot, 0);
    }

    void LateUpdate() {
        if (Input.GetKey(KeyCode.Mouse1)) {  
            float touchX = Input.GetAxis("Mouse X") * lookAtSensitivity * Time.deltaTime;
            float touchY = Input.GetAxis("Mouse Y") * lookAtSensitivity * Time.deltaTime;
            xRot -= touchY;
            xRot = Mathf.Clamp(xRot, -90f, 90f);
            transform.localRotation = Quaternion.Euler(xRot, 0f, 0f);
            parentGO.transform.Rotate(Vector3.up * touchX);
            
        }

        if (Input.GetKey(KeyCode.Space)) {
            goToPivot(target);
        }
        if (Input.GetKeyUp(KeyCode.Space)) {
            resetCamRot();
        }
    }
}

Check how the rotations take place in different gameobjects in their respective axis, so that each of rotations are kept independent and everything works.检查旋转如何在不同的游戏对象中在各自的轴上发生,以便每个旋转保持独立并且一切正常。

transform.localRotation = Quaternion.Euler(xRot, 0f, 0f); //camera GO only rotates in local x
parentGO.transform.Rotate(Vector3.up * touchX); //parent GO only rotates in global y

Problem comes when I need to "force" the camera look a certain direction without the inputs, to the FPS movement rules break, and for example the camera gameobject rotates also in the Y xis.当我需要在没有输入的情况下“强制”相机看某个方向时,问题就出现了,FPS 运动规则被打破,例如相机游戏对象也在 Y 轴上旋转。 That is why I need to call the resetCamRot() method, and traspass the local rotation from the camera object to the parent so that the situation meets the the FPS movement requirements (no local Y axis rotation).这就是为什么我需要调用resetCamRot()方法,并将相机object的局部旋转传递给父级,以使情况满足FPS运动要求(无局部Y轴旋转)。

Without calling the resetCamRot() method, when the FPS movement starts on right mouse button click, the camera abruptly changes to the direction it was facing before "forcing" it with goToPivot that sets the position and the rotation.(Just commentinf the resetCamRot method out)在不调用resetCamRot()方法的情况下,当单击鼠标右键开始 FPS 移动时,相机会突然改变到它所面对的方向,然后使用goToPivot设置 position 和旋转。(只需评论resetCamRot方法出去)

Although resetCamRot() does the work it feels a bit hacky, so is there another way to set the camera to a forced rotation maintaining the local rotation of the child object (where the camera is) to 0?虽然resetCamRot()的工作感觉有点 hacky,那么有没有另一种方法可以将相机设置为强制旋转,保持子 object(相机所在的位置)的局部旋转为 0?

I thought of decomposing the next step rotation given by Quaternion.Lerp(transform.rotation, pivot.rotation, 0.05f);我想到了分解Quaternion.Lerp(transform.rotation, pivot.rotation, 0.05f);给出的下一步旋转。 in the goToPivot() method in each of their respective axis and gameObjects as its done when the rotation is set from the input, to have a clean local Y rot in he camera gameobject each step.在它们各自的轴和游戏对象中的goToPivot()方法中,当从输入设置旋转时完成,以便在相机游戏对象的每一步中都有一个干净的局部 Y rot。 Seems to be the over-complicated thing in this case, but was not able to figure that out.在这种情况下,似乎是过于复杂的事情,但无法弄清楚。

I you wish to try the script out for the challenge just need to add a parent gameobject to the camera and the attach the target in the editor.我希望尝试脚本来应对挑战,只需将父游戏对象添加到相机并在编辑器中附加目标。

This will make the camera look in the direction, the parent transform look in the direction, only flattened, and finally update the internal state ( xRot ) in accordance with the difference between the two:这会让相机看方向,父变换看方向,只是扁平化,最后根据两者的区别更新内部 state ( xRot ):

    void LookTowards(Vector3 direction) {
        Vector3 flattened = direction;
        flattened.y = 0f;

        parentGo.rotation = Quaternion.LookRotation(flattened);
        transform.rotation = Quaternion.LookRotation(direction);
        xRot = Vector3.SignedAngle(flattened, direction, parentGo.right);
    }

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

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