【发布时间】:2022-01-16 21:35:16
【问题描述】:
考虑这个处理 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();
}
}
}
检查不同游戏对象在各自轴上的旋转是如何发生的,以便每个旋转保持独立并且一切正常。
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
当我需要在没有输入的情况下“强制”相机看某个方向时,问题就出现了,FPS 运动规则被打破,例如相机游戏对象也在 Y 轴上旋转。这就是为什么我需要调用resetCamRot()方法,并将相机对象的局部旋转越过到父对象,以使情况满足FPS运动要求(没有局部Y轴旋转)。
如果不调用resetCamRot() 方法,当FPS 移动开始于鼠标右键单击时,相机会突然改变到它所面对的方向,然后用设置位置和旋转的goToPivot“强制”它。(只需将resetCamRot 方法注释掉)
虽然resetCamRot() 的工作感觉有点hacky,但有没有另一种方法可以将相机设置为强制旋转,以保持子对象(相机所在的位置)的局部旋转为0?
我想分解由Quaternion.Lerp(transform.rotation, pivot.rotation, 0.05f); 在它们各自的轴和游戏对象中的每个轴和游戏对象中的Quaternion.Lerp(transform.rotation, pivot.rotation, 0.05f); 给出的下一步旋转,因为它在从输入设置旋转时完成,以便在其中有一个干净的局部Y rot他的相机游戏对象每一步。在这种情况下似乎是过于复杂的事情,但无法弄清楚。
如果您想尝试脚本来完成挑战,只需将父游戏对象添加到相机并在编辑器中附加目标。
【问题讨论】:
标签: c# unity3d rotation quaternions