转向最后的轮换挑战
Rotating towards a final rotation challenge
考虑这个处理 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()
做的工作感觉有点老套,但是还有另一种方法可以将相机设置为强制旋转,从而将子对象(相机所在的位置)的局部旋转保持为 0 吗?
我想分解由 Quaternion.Lerp(transform.rotation, pivot.rotation, 0.05f);
在 goToPivot()
方法中的每个轴和 gameObjects 给出的下一步旋转,就像从输入设置旋转时所做的那样,有每一步在他的相机游戏对象中都有一个干净的本地 Y 旋转。在这种情况下似乎是过于复杂的事情,但无法弄清楚。
如果您想尝试脚本来应对挑战,只需将父游戏对象添加到相机并在编辑器中附加目标即可。
这将使相机朝一个方向看,父变换朝一个方向看,仅展平,最后根据两者的区别更新内部状态(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);
}
考虑这个处理 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()
做的工作感觉有点老套,但是还有另一种方法可以将相机设置为强制旋转,从而将子对象(相机所在的位置)的局部旋转保持为 0 吗?
我想分解由 Quaternion.Lerp(transform.rotation, pivot.rotation, 0.05f);
在 goToPivot()
方法中的每个轴和 gameObjects 给出的下一步旋转,就像从输入设置旋转时所做的那样,有每一步在他的相机游戏对象中都有一个干净的本地 Y 旋转。在这种情况下似乎是过于复杂的事情,但无法弄清楚。
如果您想尝试脚本来应对挑战,只需将父游戏对象添加到相机并在编辑器中附加目标即可。
这将使相机朝一个方向看,父变换朝一个方向看,仅展平,最后根据两者的区别更新内部状态(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);
}