协同程序和while循环

时间:2016-04-08 10:21:40

标签: c# unity3d while-loop coroutine navmesh

我一直在沿着我从Navmesh Unity3d进行测试的路径上进行物体移动 我正在使用coroutine,我用while循环控制它,因为我可以显示

  public void DrawPath(NavMeshPath pathParameter, GameObject go)
{

    Debug.Log("path Parameter" + pathParameter.corners.Length);
    if (agent == null || agent.path == null)
    {
        Debug.Log("Returning");
        return;
    }

    line.material = matToApplyOnLineRenderer;
    line.SetWidth(1f, 1f);

    line.SetVertexCount(pathParameter.corners.Length);

    allPoints = new Vector3[pathParameter.corners.Length];

    for (int i = 0; i < pathParameter.corners.Length; i++)
    {
        allPoints[i] = pathParameter.corners[i];
        line.SetPosition(i, pathParameter.corners[i]);

    }

   StartCoroutine(AnimateArrow(pathParameter));

    //StartCoroutine(AnimateArrowHigh(pathParameter));
}


#endregion


#region AnimateArrows


void RunAgain()
{
    StartCoroutine(AnimateArrow(Navpath));
}

IEnumerator AnimateArrow(NavMeshPath path)
{
    Vector3 start;
    Vector3 end;

    while (true)
    {


        if (index > 0)
        {
            if (index != path.corners.Length - 1)
            {
                start = allPoints[index];

                index += 1;
                end = allPoints[index];

                StopCoroutine("MoveObject");
                StartCoroutine(MoveObject(arrow.transform, start, end, 3.0f));
                yield return null;

            }
            else
            {
                index = 0;
                RunAgain();
            }
        }
        else if (index == 0)
        {
            start = allPoints[index];
            arrow.transform.position = allPoints[index];

            index += 1;
            end = allPoints[index];


           StopCoroutine("MoveObject");
           StartCoroutine(MoveObject(arrow.transform, start, end, 3.0f));

            yield return null;
        }
    }


}

IEnumerator MoveObject(Transform arrow, Vector3 startPos, Vector3 endPos, float time)
{
    float i = 0.0f;
    float rate = 1.0f / time;
    journeyLength = Vector3.Distance(startPos, endPos);
            float distCovered = (Time.time - startTime) * speed;
            float fracJourney = distCovered / journeyLength;


    while (i < 1.0f)
    {


       // Debug.Log("fracJourney In While" + fracJourney);
        arrow.position = Vector3.LerpUnclamped(startPos, endPos, fracJourney);

        yield return endPos;
    }
    Debug.LogError("Outside While");
}

但问题是我必须以恒定的速度移动物体,但我的物体在每个循环都获得了速度,因为我必须在循环中进行移动,因此它往往会移动直到用户想要通过输入结束它 伙计们PLZ帮助我不明白我在Coroutines做错了我的物体的速度正在上升我认为它保持不变但不知何故它不能那样工作 谢谢

3 个答案:

答案 0 :(得分:1)

while (i < 1.0f)将永久运行,因为i0.0f0.0f始终为< 1.0f且您的while循环中没有位置,您可以在其中进行i {1}}这样它将> = 1.0f。你需要一种退出while循环的方法。它应该看起来像下面的东西:

while (i < 1.0f){
i++ or i= Time.detaTime..... so that this loop will exist at some point.
}

你的移动功能也很糟糕。下面的功能应该做你想做的事情:

bool isMoving = false;
IEnumerator MoveObject(Transform arrow, Vector3 startPos, Vector3 endPos, float time = 3)
{
    //Make sure there is only one instance of this function running
    if (isMoving)
    {
        yield break; ///exit if this is still running
    }
    isMoving = true;

    float counter = 0;
    while (counter < time)
    {
        counter += Time.deltaTime;
        arrow.position = Vector3.Lerp(startPos, endPos, counter / time);
        yield return null;
    }

    isMoving = false;
}

此外,在您的AnimateArrow(NavMeshPath path)功能中,替换这些三个代码行:

StopCoroutine("MoveObject");
StartCoroutine(MoveObject(arrow.transform, start, end, 3.0f));
yield return null;

yield return StartCoroutine(MoveObject(arrow.transform, start, end, 3.0f));

执行此操作将等待MoveObject函数完成,然后再返回并在while循环中再次运行。您必须在if (index != path.corners.Length - 1)else if (index == 0)

中替换这些内容

答案 1 :(得分:1)

作为替代方案,您可以使用Unity的AnimationCurve类轻松映射出各种超平滑动画类型:

enter image description here

您可以在检查器中或代码中定义曲线

g

您可以在协程中定义用法:

 public AnimationCurve Linear
{
    get
    {
        return new AnimationCurve(new Keyframe(0, 0, 1, 1), new Keyframe(1, 1, 1, 1));
    }
}

“percentCompleted”是你的计时器/ TotalTimeToComplete。

从这个函数中可以看到完整的lerping示例:

Vector2.Lerp (startPos, targetPos, aCurve.Evaluate(percentCompleted));

查看此Tween库以获取更多代码示例:https://github.com/James9074/Unity-Juice-UI/blob/master/Juice.cs

答案 2 :(得分:0)

也许你可以将速度乘以0.95f。这将使其加速,然后保持恒定速度,然后当您希望它停止时它将逐渐减速。增加 0.95f 将使其加速/减速更快。