Coroutines and while loop

前端 未结 3 1507
说谎
说谎 2021-01-27 06:51

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

相关标签:
3条回答
  • 2021-01-27 07:14

    Maybe you could multiply the velocity by, say, 0.95f. This will make it accelerate, then stay at a constant speed, and then when you want it to stop it will gradually decelerate. Increasing the 0.95f will cause it to accelerate/decelerate faster.

    0 讨论(0)
  • 2021-01-27 07:28

    while (i < 1.0f) will run forever because i is 0.0f and 0.0f is always < 1.0f and there is no place inside your while loop, where you increement i so that it will >= 1.0f. You need a way to exit that while loop. It should have looked like something below:

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

    Also your moving function is bad. The function below should do what you are trying to do:

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

    Also, in your AnimateArrow(NavMeshPath path) function, replace these three lines of code:

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

    with

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

    Doing this will wait the MoveObject function to finish before returning and running again in the while loop. You have to replace these inside if (index != path.corners.Length - 1) and else if (index == 0)

    0 讨论(0)
  • 2021-01-27 07:36

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

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

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

    0 讨论(0)
提交回复
热议问题