这里是菜鸟/初学者。我已经搜索过这个问题,但我自己没有找到任何内容(如果这个问题已经在这里解决/回答,我深表歉意)。我正在按照本教程制作一个超级基本的 FP 角色控制器 (https://www.youtube.com/watch?v=PmIPqGqp8UY)。这太棒了,我已经让它工作了,但我一路上遇到了一些问题,我真的很想知道为什么。最终的脚本如下所示(缺少一些将鼠标锁定到屏幕中心的代码):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovementScript_V3 : MonoBehaviour
{
[SerializeField] Transform playerChar_FP_POV = null;
[SerializeField] float mouseSensitivty = 3.5f;
float cameraPitch = 0.0f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
PlayerCameraControl();
}
public void PlayerCameraControl()
{
Vector2 mouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
cameraPitch -= mouseDelta.y;
cameraPitch = Mathf.Clamp(cameraPitch, -90.0f, 90.0f);
playerChar_FP_POV.localEulerAngles = Vector3.right * cameraPitch;
transform.Rotate(Vector3.up * mouseDelta.x * mouseSensitivty);
}
}
其中 SerializeField 变换“playerChar_FP_POV”是一个已将相机(“PlayerChar_Body”的子对象)拖入其中的字段,因此可以从脚本访问其变换(请参见附图 1显示序列化字段变换的图像附于
在实验时,我发现无法将“mouseDelta.y”直接传递到“PlayerChar_FP_POV”X 旋转变换(上面脚本的倒数第二行),就像将 mouseDelta.x 传递到“PlayerChar_Body”Z 旋转一样转换(上面脚本的最后一行)。我首先必须创建一个浮点“cameraPitch”,然后将其值分配给 mouseDelta.y 的倒数(cameraPitch -= mousedelta.y),然后使用 Mathf.Clamp 限制“cameraPitch”的范围(上面的脚本 - 在最后一个方法中) )。然后,也只有这样,我才能成功地将值传递给“player_FP_Pov”以更改其 X 旋转变换。如果我尝试像这样将 mousedelta.y 直接传递到“playerChar_FP_POV”的 X 变换中(查看最后一个方法):
public void PlayerCameraControl()
{
Vector2 mouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
playerChar_FP_POV.localEulerAngles = Vector3.right * mouseDelta.y;
transform.Rotate(Vector3.up * mouseDelta.x * mouseSensitivty);
}
(将 mouseDelta.y 直接传递到“playerChar_FP_POV”X 旋转变换;省略夹紧相机范围和反转输入)
“PlayerChar_FP_POV”(玩家相机)的 X 旋转变换被锁定到位,并且不响应鼠标 Y 轴移动(见图)。 父对象可以在其 Z 轴上跟随鼠标 x 轴,子对象不能在其 x 轴上跟随鼠标 Y 轴
再次,我的控制器工作正常。但纯粹从教育角度来看,我试图找出为什么后一个代码块不起作用。我觉得理解这会进一步加深我的理解。我希望这足够清楚,不想浪费人们的时间!
Unity版本:2022.3.22f1
为阅读本文干杯!
上面解释的问题,本节并不完全适用。
这是因为
Input.GetAxis("Mouse Y")
又名 mouseDelta.y
是自上一帧以来鼠标垂直移动的距离,也就是说,上一次 Update
被调用。
在第一个示例中,
cameraPitch
充当记录前一帧上的旋转状态的方式:
cameraPitch -= mouseDelta.y;
// clamping goes here... omitting for clarity
playerChar_FP_POV.localEulerAngles = Vector3.right * cameraPitch;
通过这种方式,它被用来对基于前一帧的旋转进行更改,这与
mouseDelta.y
本身是基于前一帧的更改是一致的。
为了让这个想法更清晰,你可以这样想:
// this doesn't actually change anything because this is already true based on
// what happened the last time PlayerCameraControl() was called
cameraPitch = playerChar_FP_POV.localEulerAngles.x;
cameraPitch -= mouseDelta.y;
// clamping goes here... omitting for clarity
playerChar_FP_POV.localEulerAngles = Vector3.right * cameraPitch;
在第二个示例中,尝试将其单独用作旋转的绝对度量。请注意,前一帧中的旋转没有任何涉及,它只是被完全覆盖:
playerChar_FP_POV.localEulerAngles = Vector3.right * mouseDelta.y;
进一步说明的一个小比喻...
鲍勃一开始有 90 个苹果。每天,爱丽丝都会给鲍勃一定数量的苹果,或者拿走一定数量的苹果。每天,你可以问爱丽丝她给了鲍勃多少个苹果,或者她拿走了多少个。
如果您需要预测鲍勃目前每天结束时有多少个苹果……您不能只使用爱丽丝告诉您的数量,对吧?您需要记住鲍勃一开始有多少,然后根据爱丽丝拿走或给予的金额更新该金额。
您基本上是在这样做,但是鼠标在旋转中“给予”或“获取”的程度不同。