[英]How can I get my camera to momentarily pause between different positions when using lerp in Unity3D?
I have an array of positions that I want my camera to move/lerp between. 我有一系列位置,我希望相机在它们之间移动/固定。 There are two buttons (button A and button B) that trigger the camera to move position. 有两个按钮(按钮A和按钮B)触发相机移动位置。 If the user presses button A, the camera will lerp to the previous position in the array. 如果用户按下按钮A,则摄像机将束紧到阵列中的上一个位置。 If the user presses button B, the camera will lerp to the next position in the array. 如果用户按下按钮B,则摄像机将跳至阵列中的下一个位置。 However, before moving to a new position, I want the camera to lerp to an intermediate position, pause there for a couple of seconds, and then move. 但是,在移动到新位置之前,我希望照相机将镜头拉到中间位置,在那里暂停几秒钟,然后再移动。 Here is the pseudocode for what I have at the moment: 这是我目前所拥有的伪代码:
void Update()
{
if (buttonPress == a) {
positionToMoveTo = positions[currentPosition--];
}
if (buttonpress == b) {
positionToMoveTo = positions[currentPosition++];
}
}
void LateUpdate()
{
camera.lerp(intermediatePosition);
StartCoroutine(pause());
}
IEnumerator pause()
{
yield return new WaitForSeconds(3f);
camera.lerp(positionToMoveTo);
}
This doesn't work though because I get strange jittering when switching camera positions and my intermediate position doesn't always occur. 但是,这不起作用,因为在切换相机位置时出现奇怪的抖动,并且中间位置并不总是出现。 I think my problem has something to do with execution order but I can't figure it out. 我认为我的问题与执行顺序有关,但我无法弄清楚。 Any help would be great :) 任何帮助将是巨大的:)
You start a new Coroutine every frame since LateUpdate
runs every frame after all Update
calls are finished! 您可以在每帧开始新的协程,因为LateUpdate
在所有Update
调用完成后LateUpdate
运行每帧!
You could avoid this by a slightly different approach: 您可以通过稍微不同的方法来避免这种情况:
private bool isIntermediate;
private bool moveCamera;
private void LateUpdate ()
{
if(!moveCamera) return;
if(isIntermediate)
{
camera.lerp(intermediatePosition);
}
else
{
camera.lerp(positionToMoveTo);
}
}
private IEnumerator MoveCamera()
{
moveCamera = true;
isIntermediate=true;
yield return new WaitForSeconds(3f);
isIntermediate=false;
// Wait until the camera reaches the target
while(camera.transform.position == PositionToMoveTo){
yield return null;
}
// Stop moving
moveCamera = false;
// just to be sure your camera has exact the correct position in the end
camera.transform.position = PositionToMoveTo;
}
Alternatively you could do all the movement in the Coroutine without LateUpdate
(but honestly I'm not sure if the Coroutines are done before or after Update
) 或者你可以做所有的动作在协程没有LateUpdate
(但老实说,我不知道,如果协同程序之前或之后进行Update
)
private IEnumerator MoveCamera()
{
float timer = 3f;
while(timer>0)
{
timer -= Time.deltaTime;
camera.lerp(intermediatePosition);
yield return null;
}
// Wait until the camera reaches the target
while(camera.transform.position == PositionToMoveTo){
camera.lerp(PositionToMoveTo);
yield return null;
}
// just to be sure your camera has exact the correct position in the end
camera.transform.position = PositionToMoveTo;
}
This second one would be cleaner bjt as said I don't know if it is a requirement for you to have it run in LateUpdate
第二个会更干净bjt,因为我不知道是否需要在LateUpdate
运行它
Note : the ==
operator of Vector3 has a precision of 0.00001
. 注意 :Vector3的==
运算符的精度为0.00001
。 If you need a better or weaker precision you have to change to 如果需要更高或更小的精度,则必须更改为
if(Vector3.Distance(camera.transform.position, PositionToMoveTo) <= YOUR_DESIRED_THRESHOLD)
Now all you have to do is to call your Coroutine Everytime you want to change the camera position. 现在,您要做的就是每次要更改相机位置时都呼叫协程。
void Update()
{
if (buttonPress == a)
{
// Make sure the Coroutine only is running once
StopCoroutine(MoveCamera);
positionToMoveTo = positions[currentPosition--];
StartCoroutine (MoveCamera);
}
if (buttonpress == b)
{
// Make sure the Coroutine only is running once
StopCoroutine (MoveCamera);
positionToMoveTo = positions[currentPosition++];
StartCoroutine (MoveCamera);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.