2017-03-05 104 views
0

我想順利地從我目前的位置移動到,我已經硬編碼一個新的位置,但即使使用Vector3.LerpVector3.MoveTowards它只是移動播放器通常沒有任何延遲效應。Vector3.Lerp不工作

我也嘗試在Vector3.Lerp方法中添加Time.deltaTime,但它只是將播放器稍微移動一點。我只想讓玩家順利地走向設定的位置。

我是新來的團結和任何幫助,將不勝感激。

public class PlayerControl : MonoBehaviour { 
    //change position 
    private float leftX = -1.65f; 
    private float leftY = 0.00f; 
    private float rightX = -1.00f; 
    private float rightY = -1.13f; 

    private Vector3 carPosition; 
    private float slowTime = 2f; 

    void Start() { 
     //set the player to its current position 
     carPosition = transform.position; 
    } 

    void Update() { 
     //control the player 
     if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0)) { 
      Debug.Log("Pressed!"); 

      if(transform.position.y <= -0.5) { 
       carPosition.x = leftX; 
       carPosition.y = leftY; 
      } 

      if(transform.position.y >= 0) { 
       carPosition.x = rightX; 
       carPosition.y = rightY; 
      } 

      //transform.position = carPosition; 
      transform.position = Vector3.Lerp(transform.position, carPosition, slowTime); 
     } 
    } 
} 

回答

1

編輯:重新寫的答案,如何更好地解釋Lerp作品。

Lerp以非常簡單的方式工作:我們稱之爲參數V1,V2和perc - result = Vector3.Lerp(V1, V2, perc)

比方說V1 = (0,0,0),V2 = (1,0,0)perc = 0,2f。使用這些固定參數,您可以獲得result = 0.2f,或者換句話說,從V1開始,您可以得到一個Vector3接近V2的百分比perc。

現在,如果要以固定的步驟將對象從V1移動到V2,則需要調用每個Update()來修改參數perc。例如,如果您想要以5個單一步驟到達目的地,那麼您需要使用以下序列perc0.2 - 0.4 - 0.6 - 0.8 - 1調用Lerp 5次。你想用10步移動對象?然後你使用序列0.1 - 0.2 - 0.3等,你明白了。

但是做事情的這種方式給你一個波濤洶涌的動畫,所以要使用傳遞給計算多少時間是perc參數每Update(示例代碼是由盧卡斯提供的鏈接),以獲得平滑的和從頭到尾的線性運動。

所以,你的類應該是這樣的:

using UnityEngine; 

public class PlayerControl : MonoBehaviour {  

    private float leftX = -1.65f; 
    private float leftY = 0.00f; 
    private float rightX = -1.00f; 
    private float rightY = -1.13f; 
    private float speed = 2f, startTime, totalDistance = 0f; 
    private Vector3 carPosition, startPos; 

    void Start() { 
     carPosition = transform.position; 
     startPos = carPosition; 
    } 

    void Update() { 
     if (Input.GetKeyDown (KeyCode.Space) || Input.GetMouseButtonDown (0)) { 
      Debug.Log ("Pressed!"); 
      startTime = Time.time; 
      if (transform.position.y <= -0.5) { 
       startPos = transform.position; 
       carPosition.x = leftX; 
       carPosition.y = leftY; 
      } 
      if (transform.position.y >= 0) { 
       startPos = transform.position; 
       carPosition.x = rightX; 
       carPosition.y = rightY; 
      } 
      totalDistance = Vector3.Distance(startPos, carPosition); 
     } 
     if (startPos != carPosition) { 
      float newPercentageBetweenVectors = (Time.time - startTime) * speed/totalDistance; 
      transform.position = Vector3.Lerp (startPos, carPosition, newPercentageBetweenVectors); 
     } 
    } 
} 

使用線性插值到移動對象的另一種方法是保持一個固定的perc和使用作爲第一個參數的對象的位置。這會給你一個對數類型的移動,開始時速度越快,越靠近目的地越慢,但要注意,由於它是一個漸近線,你永遠不會達到它 - 這意味着你需要自己檢查一下如果當前位置是足夠接近一個特定的距離的最終位置,例如10^-2,具有這樣的代碼:

using UnityEngine; 

public class PlayerControl : MonoBehaviour { 

    private float leftX = -1.65f; 
    private float leftY = 0.00f; 
    private float rightX = -1.00f; 
    private float rightY = -1.13f; 
    private float speed = 2f, totalDistance; 
    private Vector3 carPosition; 

    void Start() { 
     carPosition = transform.position; 
    } 

    void Update() { 
     if (Input.GetKeyDown (KeyCode.Space) || Input.GetMouseButtonDown (0)) { 
      Debug.Log ("Pressed!"); 
      if (transform.position.y <= -0.5) { 
       carPosition.x = leftX; 
       carPosition.y = leftY; 
      } 
      if (transform.position.y >= 0) { 
       carPosition.x = rightX; 
       carPosition.y = rightY; 
      } 
     } 
     if (transform.position != carPosition) { 
      transform.position = Vector3.Lerp (transform.position, carPosition, speed * Time.deltaTime); 
      totalDistance = Vector3.Distance(transform.position, carPosition); 
      if (totalDistance < Mathf.Pow(10,-2)) transform.position = carPosition; 
     } 
    } 
} 

在這種情況下使用的Time.deltaTime是沒有必要的,如果提供了足夠低speed。 這個第二次使用Lerp特別指出(並且實際上廣泛使用)將相機移動到遊戲對象。

+0

Lerp不是一個單一的步驟如果你想要這種行爲,請使用MoveTowards – CaTs

+0

當然,我用一個不恰當的方式使用術語步驟,我將編輯我的答案以更好地解釋Lerp是如何工作的。 – Galandil

+1

非常感謝你的工作。因爲我是Unity的新手,Lerp的概念對於我的項目來說很難理解,你提供的答案對我來說很重要,但對我來說卻很小,但我理解了它背後的邏輯。我猜我需要學習很多東西。你的答案真的很感激。 – pijushmandal

2

你的錯誤是在這裏:

transform.position = Vector3.Lerp(transform.position,carPosition,slowTime);

不要使用transfrom.position作爲參數。使用一些指定startPosition變量作爲

transform.position = Vector3.Lerp(指定startPosition,carPosition,slowTime);

另外slowTime應行進被夾持的距離的一小部分爲[0,1]。當你把2f放在那裏時,你會立即移動到終點。把0.5f放在那裏,看看我在說什麼。

請檢查: https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html

+0

startPosition與transform.position相同,遊戲就是這樣工作的;當我按下按鍵時,它切換到不同的位置,並且在我按下鍵時在兩個提供的位置之間交換我也嘗試了slowTime = 0.5f,但它只是沒有達到所需的位置,如果我將slowTime的值設置爲1f以上,結果是相同的太快了。 – pijushmandal

+0

@ŁukaszMotyczka如果您使用固定的起始矢量在'Lerp'裏面,你需要每次調用它時更新這個步驟,否則返回的值將永遠是每個'Lerp'調用。它在你提供的鏈接的代碼中。 – Galandil

0

這是我學會了做它的方式:

創建一個新的協程(IEnumerator的標題){}。

創建一個名爲t的浮點數。其值分配給0

使while循環:

while(t < 1){ 

} 

類型在「T + = Time.deltaTime /速度

待辦事項transform.position = Vector3.Lerp(transform.position, 。carPosition,T);

待辦事項產量返回NULL

這是我學到的方式你完成的代碼應該是這樣的:

IEnumerator Drive(){ 
    float t = 0; 
    while(t < 1){  
     t += Time.deltaTime/speed;  
     transform.position = Vector3.Lerp(transform.position, carPosition, t); 
     yield return null;  
    } 
} 

還記得啓動協程。 (StartCoroutine(Drive());