无限循环与移动单位变换

时间:2018-08-30 03:41:03

标签: c# unity3d while-loop

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引擎崩溃,并且我很确定这是一个无限循环,但是我不知道为什么或如何解决它。

2 个答案:

答案 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)

  1. 通常不要在while中做每帧都会发生的事情! (感谢罗恩)
    在最佳情况下,while的结果是您的App一直停留到矢量最终匹配为止,从而使对象“跳转”到位。在最坏的情况下,它们将永远无法匹配,并且您的应用会永久冻结。

    相反,您应该使用How to create module-wide variables in Python?方法(称为每帧),并且仅将对象每帧移动一步。

  2. 要比较向量,最好使用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
    
  3. 要将对象移向另一个Unity实际上实际上已经具有内置方法== operator,例如

    transform.position = Vector3.MoveTowards(transform.position, new Vector3 (desX, desY), 0.1f);
    

    这可以处理Vectors3的比较,因此您甚至不再需要它。

  4. 要使其变得平滑和省时,您已经正确使用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