如何在Unity中的两点之间移动对象? [英] How to move an object between two points in Unity?
问题描述
我正在尝试使用unity的lerp
功能将棋子向上,横向平移,然后向下平移.但是,无论何时触发此脚本,整个会话都会冻结.
I am attempting to translate a chess piece up, across and then back down using the lerp
functionality of unity. However, whenever I trigger this script, the entire session freezes.
使用统一调试器,我将问题缩小到此部分代码.
Using the unity debugger, I have narrowed the problem down to this section of code.
do
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
Debug.Log(fracJourney);
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
} while (fracJourney <= 1);
因为看起来所有变量都没有改变,因此整个循环是无限的.
because it would appear that none of the variables are altering and consequently, the entire loop is infinite.
这是专用于处理运动的代码的整个部分(矢量值目前是任意的).
Here is the entire section of code dedicated to handling the movement (the vector values are currently arbitrary).
public class MovePiece : MonoBehaviour {
Vector3 startPoint;
Vector3 endPoint;
float speed = 10;
float startTime;
private bool moving = false;
private bool up = false;
private bool across = false;
private bool down = false;
public void Start()
{
startPoint = gameObject.GetComponent<Transform>().position;
startTime = Time.time;
moving = true;
Debug.Log("Moving Piece");
}
void Update() {
if (!moving)
{
Destroy(this);
return;
}
moveManager();
}
void moveManager()
{
if (!up)
{
lerpUp();
return;
}
if (!across)
{
lerpAcross();
return;
}
if (!down)
{
lerpDown();
return;
}
}
private void lerpUp()
{
Debug.Log("Upwards");
startPoint = gameObject.GetComponent<Transform>().position;
endPoint = startPoint + new Vector3(0, 0, 50);
float journeyLength = Vector3.Distance(startPoint, endPoint);
float fracJourney;
do
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
Debug.Log(fracJourney);
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
} while (fracJourney <= 1);
up = true;
Debug.Log("Upwards Finished");
return;
}
private void lerpAcross()
{
Debug.Log("Across");
startPoint = gameObject.GetComponent<Transform>().position;
endPoint = startPoint + new Vector3(0, 50, 0);
float journeyLength = Vector3.Distance(startPoint, endPoint);
float fracJourney;
do
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
} while (fracJourney <= 1);
across = true;
Debug.Log("Across Finished");
return;
}
private void lerpDown()
{
Debug.Log("Down");
startPoint = gameObject.GetComponent<Transform>().position;
endPoint = startPoint + new Vector3(0, 0, -50);
float journeyLength = Vector3.Distance(startPoint, endPoint);
float fracJourney;
do
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
} while (fracJourney <= 1);
down = true;
Debug.Log("Down Finished");
moving = false;
Debug.Log("Moving Finished");
return;
}
}
}
我已经尝试了好几天来缩小此问题的范围,但无济于事,因此不胜感激.
I have been trying for days to narrow this problem down, to no avail, so any help would be greatly appreciated.
推荐答案
do
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
Debug.Log(fracJourney);
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
} while (fracJourney <= 1);
Update()
每帧仅运行一次,并且Time
仅在更新时更新,因此Time
不会因为一个Update()
的变化而变化,因此(Time.time - startTime) * speed
始终保持不变,因此distCovered
永远不会改变,所以fracJourney
永远不会改变,所以fracJourney <= 1
永远不会改变,所以您永远陷入循环之中.
Update()
only runs once per frame, and Time
only gets updated when it does, so Time
will never change in the matter of one Update()
, so (Time.time - startTime) * speed
will always stay the same, so distCovered
will never change, so fracJourney
will never change, so fracJourney <= 1
will never change, so you are stuck in the loop forever.
如果您正在寻找修复程序,几乎不需要在Update()
函数内部需要一个while
循环.使用Update()
函数本身作为循环,或使用IEnumerator
在其中可以屈服并让帧通过,例如:
If you are looking for a fix, you shouldnt need a while
loop inside of an Update()
function, almost ever. Use the Update()
function itself as your loop, or use an IEnumerator
where you can yield out and let a frame pass, as such:
public IEnumerator MyLoop()
{
while (fracJourney <= 1)
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
Debug.Log(fracJourney);
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
yield return null; //< --- yield out and let a frame pass
}
}
这篇关于如何在Unity中的两点之间移动对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!