协程和while循环 [英] Coroutines and while loop

查看:721
本文介绍了协程和while循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在沿着从Navmesh Unity3d获取的路径进行对象移动 我正在使用协程,其中我可以通过while循环对其进行控制

I have been working on a object movement along a path Which i have been geting from Navmesh Unity3d I am using coroutine in which i controled it with while loop as i can show

  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");
}

但是问题是我必须以恒定的速度移动对象,但是我的对象在每个循环中都在加快速度,因为我必须在一个循环中进行移动,因此它倾向于移动,直到用户希望通过输入结束它为止 伙计们请帮助我不明白我在Coroutines中做错了什么,我的物体的速度正在提高,我希望它保持恒定,但是以某种方式无法正常工作 谢谢

But the problem is i have to move object on a constant speed but my object is gaining speed at every loop as i have to make movement in a loop so it tends to move until user wants to end it by input guys plz help i dont understand what i am doing wrong in Coroutines that the speed of my objects is rising i wat it to stay constant but somehow its not working that way thanks

推荐答案

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

As an alternative, you could utilize Unity's AnimationCurve class to map out all kinds of super smooth animation types easily:

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

You can define the curves in the inspector, or in code

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

您可以这样定义协程中的用法:

And you can define useage in a coroutine as such:

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

其中"percentCompleted"是您的计时器/TotalTimeToComplete.

Where "percentCompleted" is your timer/TotalTimeToComplete.

从此功能可以看到完整的示例:

A full example of lerping can be seen from this function:

    IEnumerator CoTween(RectTransform aRect, float aTime, Vector2 aDistance, AnimationCurve aCurve, System.Action aCallback = null)
{
    float startTime = Time.time;
    Vector2 startPos = aRect.anchoredPosition;
    Vector2 targetPos = aRect.anchoredPosition + aDistance;
    float percentCompleted = 0;
    while(Vector2.Distance(aRect.anchoredPosition,targetPos) > .5f && percentCompleted < 1){
        percentCompleted = (Time.time - startTime) / aTime;
        aRect.anchoredPosition = Vector2.Lerp (startPos, targetPos, aCurve.Evaluate(percentCompleted));
        yield return new WaitForEndOfFrame();
        if (aRect == null)
        {
            DeregisterObject(aRect);
            yield break;
        }
    }
    DeregisterObject(aRect);
    mCallbacks.Add(aCallback);
    yield break;
}

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

Check out this Tween library for more code examples: https://github.com/James9074/Unity-Juice-UI/blob/master/Juice.cs

这篇关于协程和while循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆