2016-04-08 36 views
0

我一直在努力沿着我已經從導航網格Unity3d歌廳 我使用的協同程序中,我與while循環controled它的路徑中的物體運動,因爲我可以顯示協同程序和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"); 
} 

但問題是我必須以恆定的速度移動對象,但是我的對象在每個循環中都獲得了速度,因爲我必須在循環中進行移動,所以它往往會移動,直到用戶想要通過輸入來結束它。 guys plz help i dont瞭解我在Coroutines中做錯了什麼,我的物體速度正在上升,我保持不變,但不知何故它不是那樣工作的 謝謝

回答

0

也許你可以乘以速度,比如0.95f。這會使它加速,然後保持恆定的速度,然後當你想停止時它會逐漸減速。增加0.95f將使其加速/減速更快。

1

while (i < 1.0f)將永遠運行,因爲i0.0f0.0f總是< 1.0f並有while循環,在那裏你increement i,這樣它會> = 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)

+0

感謝快速響應,但它不解決我做了什麼你建議,但它做同樣的事情獲得速度作爲它從路徑末端的循環 –

+0

剛體連接到這個gameObject? – Programmer

+0

沒有他們是沒有剛體或甚至對撞機我一直在搜索谷歌整天,但還沒有找到解決方案,我認爲這不是一個正確的方法來做到這一點 –

1

作爲替代方案,你可以利用統一的AnimationCurve類輕鬆繪製出各種超流暢的動畫類型:

enter image description here

您可以定義曲線檢查員,或在代碼

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

而且你可以在協程這樣定義用途:

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

其中「percentCompleted」是您的計時器/ TotalTimeToComplete。

lerping的完整例子可以利用此功能可以看出:

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

看看這個吐溫庫更多代碼示例:https://github.com/James9074/Unity-Juice-UI/blob/master/Juice.cs