现在我有2个摄像头:主摄像头显示枪处于正常状态,第二个摄像头连接到枪上(枪是主摄像头的孩子),当切换时,它看起来是通过枪,增加了视野。
为了更好的理解,这是一个视觉效果:
现在,如果我只是打开第二台摄像机并关闭主摄像头,这将非常出色,但它并不是很理想。每个场景只能有1个摄像头。
因此,我希望Lerp相机的位置以查看示波器并手动减少fieldofview。所以我写了以下脚本:
[RequireComponent(typeof(Camera))]
public class Zoom : MonoBehaviour {
private Transform CameraTransform = null;
public Transform ZoomedTransform;
private bool zoomed = false;
void Start () {
CameraTransform = Camera.main.transform;
}
// Update is called once per frame
void Update () {
if (Input.GetKey (KeyCode.LeftShift))
{
CameraTransform.position = Vector3.Lerp (
CameraTransform.position,
CameraTransform.position + ZoomedTransform.position,
5f * Time.deltaTime
);
CameraTransform.Rotate(ZoomedTransform.rotation.eulerAngles);
}
}
}
问题在于它不起作用:当我按下变焦按钮时,相机以光速在场景中加速,并且很难确切地知道发生了什么。
有人能给我一些关于我做错了什么的见解吗?我认为这与父子关系有关,但即使我尝试使用静态值,我似乎无法复制正确的解决方案。
层次:
答案 0 :(得分:1)
你的lerp目标是相对于相机的当前位置,所以它不断移动。这是你的目标:
CameraTransform.position + ZoomedTransform.position
这意味着当相机移动到接近此位置时,相机的新位置会导致目的地发生变化。所以你的相机一直在移动。
您的目的地应为ZoomedTransform.position
。因position
is in world coordinates而无需添加。 (当你真的需要在空格之间进行转换时,请查看TransformPoint
和类似的方法。)
答案 1 :(得分:1)
(这个答案是在假设ZoomedTransform
是相对转换的情况下运行的,而不是31eee384的回答所怀疑的相机的绝对位置。)
我认为您的代码存在一些问题。我会单独处理它们,这样它们更容易理解,但它们都与以下几行有关:
CameraTransform.position = Vector3.Lerp (CameraTransform.position, CameraTransform.position + ZoomedTransform.position, 5f * Time.deltaTime);
首先,让我们看看你如何使用Vector3.Lerp()
。对于Vector3.Lerp()
的第三个参数,您提供5f * Time.deltaTime
。这个价值究竟到底是什么?那么,标准帧率约为60 FPS,因此Time.deltaTime
= ~1 / 60。因此,5f * Time.deltaTime
= 5/60 = ~0.0833。
但Vector3.Lerp()
期望第三个参数是什么?根据{{3}},第三个参数应该在0和1之间,并确定返回的Vector3
是否应该更靠近第一个或第二个Vector3
。所以是的,5f * Time.deltaTime
落在这个范围内,但不会发生插值 - 因为它总是在~0.0833左右,而不是从0进展到1(或1到0)。每一帧,你基本上都会回来cameraPos + zoomTransform * 0.0833
。
另一个值得注意的问题是你如何每帧更新CameraTransform.position
的值,然后使用新的(增加的)值作为下一帧Vector3.Lerp()
的参数。 (这有点像在循环中执行int i = i + 1;
。)这就是为什么你的相机如此快速地飞越地图的原因。以下是每帧的情况,使用我之前计算的Vector3.Lerp()
的假设结果(伪代码):
// Frame 1
cameraPosFrame_1 = cameraPosFrame_0 + zoomTransform * 0.0833;
// Frame 2
cameraPosFrame_2 = cameraPosFrame_1 + zoomTransform * 0.0833;
// Frame 3
cameraPosFrame_3 = cameraPosFrame_2 + zoomTransform * 0.0833;
// etc...
每一帧zoomTransform * 0.0833
都会被添加到相机的位置。最终真正,快速,不间断地增加价值 - 所以你的相机飞过地图。
解决这些问题的一种方法是使用变量来存储相机的初始本地位置,缩放进度和缩放速度。这样,我们永远不会丢失相机的原始位置,我们可以跟踪变焦进展的距离以及何时停止它。
[RequireComponent(typeof(Camera))]
public class Zoom : MonoBehaviour {
private Transform CameraTransform = null;
public Transform ZoomedTransform;
private Vector3 startLocalPos;
private float zoomProgress = 0;
private float zoomLength = 2; // Number of seconds zoom will take
private bool zoomed = false;
void Start () {
CameraTransform = Camera.main.transform;
startLocalPos = CameraTransform.localPosition;
}
// Update is called once per frame
void Update () {
if (Input.GetKey (KeyCode.LeftShift))
{
zoomProgress += Time.deltaTime;
CameraTransform.localPosition = Vector3.Lerp (startLocalPos, startLocalPos + ZoomedTransform.position, zoomProgress / zoomLength);
CameraTransform.Rotate(ZoomedTransform.rotation.eulerAngles);
}
}
}
希望这有帮助!如果您有任何疑问,请告诉我。这个答案确实有些絮絮叨叨,所以我希望你从中获得重点不会有任何麻烦。