while (transform.position != new Vector3(desX, desY))
{
// 2 - Movement
Vector3 movement = new Vector3(
0.1f * desX,
0.1f * desY,
0);
//movement *= Time.deltaTime;
transform.Translate(movement);
}
我的程序的这一部分使Unity引擎崩溃,并且我很确定这是一个无限循环,但是我不知道为什么或如何解决它。
答案 0 :(得分:4)
这冻结了您的应用程序,因为当while
循环中的条件不满足时,您没有给其他脚本运行的机会。
要修复将该代码放入协程函数的问题,然后将yield return null;
添加到while
循环中。这使得Unity在每个循环之后等待一帧,因此给其他脚本运行每个帧的机会。无论while
循环是否退出,这都应该解决冻结问题。我还建议您使用Vector3.Distance
来确定您何时接近目的地。
public float reachThreshold = 0.2f;
void Start()
{
StartCoroutine(MoveBject());
}
IEnumerator MoveBject()
{
float distance = Vector3.Distance(transform.position, new Vector3(desX, desY));
while (distance > reachThreshold)
{
// 2 - Movement
Vector3 movement = new Vector3(
0.1f * desX,
0.1f * desY,
0);
//movement *= Time.deltaTime;
transform.Translate(movement);
//Wait a frame
yield return null;
}
}
如果您确实想随着时间的推移将GameObject移到另一个位置,请参阅this帖子。
答案 1 :(得分:3)
通常不要在while
中做每帧都会发生的事情! (感谢罗恩)
在最佳情况下,while
的结果是您的App一直停留到矢量最终匹配为止,从而使对象“跳转”到位。在最坏的情况下,它们将永远无法匹配,并且您的应用会永久冻结。
相反,您应该使用How to create module-wide variables in Python?方法(称为每帧),并且仅将对象每帧移动一步。
要比较向量,最好使用Update()
。对于Vector3
使用Vector3.Distance
基本上是可以的,但是在内部它等于
Vector3.Distance(vectorA, vectorB) <= 0.00001f
使用的阈值很小,可能不完全匹配。因此,您可以使用Vector3.Distance
设置自己的阈值,例如到0.1
以使其更容易匹配。
bool match = Vector3.Distance(transform.position, new Vector3(desX, desY) < 0.1f
要将对象移向另一个Unity实际上实际上已经具有内置方法==
operator,例如
transform.position = Vector3.MoveTowards(transform.position, new Vector3 (desX, desY), 0.1f);
这可以处理Vectors3的比较,因此您甚至不再需要它。
要使其变得平滑和省时,您已经正确使用Time.deltaTime
。没有这个,它将移动0.1 meters / frame
,但您的帧率可能不稳定。使用Time.deltaTime
使其成为0.1 meters / second
,几乎在所有情况下,这都是您实际要实现的目标。
因此,将它们放在一起,代码应该类似于
float desX;
float desY;
float moveSpeed = 0.1f;
void Update()
{
var targetPosition = new Vector3 (desX, desY);
transform.position = Vector3.MoveTowards(transform.position, targetPosition, moveSpeed * Time.deltaTime);
}
请注意,在某些情况下,MoveTowards
仍然无法中继,例如如果您想跟踪碰撞或其他情况。在这种情况下,请参考Vector3.MoveTowards