[英]Unity linear Interpolation for smooth 3D movement
所以我正在嘗試創建一個向前運行的游戲(類似於 Temple Run),但我希望我的角色能夠順利地左右移動,而不僅僅是傳送。 我嘗試使用Vector3.Lerp()
但我無法理解它是如何工作的。
這是我嘗試過的,但角色只是瞬移
void Update()
{
if(Input.GetKeyDown("a")&&lane-1>0)
{
lane-=1;
shouldMove = true;
Vector3 newpos= new Vector3(transform.position.x -2.5f, transform.position.y, transform.position.z);
while (shouldMove)
{
transform.position = Vector3.Lerp(transform.position, newpos, 0.1f * Time.deltaTime);
if(transform.position.x>=newpos.x)
{
shouldMove = false;
transform.position = newpos;
}
}
此示例僅用於向左移動。
您認為使用Vector3.Lerp
在開始值和結束值之間逐漸插值是正確的。 但是,實現和用例並不完全適合您嘗試做的事情。
由於您僅更改運動的單個軸,因此我不會使用Vector3.Lerp
,而是使用Mathf.Lerp
因為您僅更改 position 的 x 軸。
您使用的是while
循環而不是Update
,這意味着程序將停留在該循環內,直到該過程完成。 它立即移動到下一點的原因是由於您的if
條件。 您從當前值中減去2.5
,然后不斷檢查當前 position x 是否大於新值,這始終是正確的。 它會立即將您當前的 position 設置為您的新 position,然后跳出您的 while 循環。 另一個問題是您正在使用GetKeyDown
,它只發生在用戶單擊鍵的一幀。 Lerps
意味着隨着時間的推移完成,而不是立即完成。
與其將您的邏輯放在Update
中,我會考慮將實際運動移至稱為 Coroutine 的特殊Coroutine
。 將Courtines
想象為一個在多個幀上完成的過程,然后跳回到上一幀中斷的地方。 Coroutines
非常強大,但請在過度使用它們之前仔細閱讀文檔,以深入了解它們的作用。
現在進行實施。 我不完全確定你的車道設置,但會假設你有 3 條車道,類似於其他無限跑道游戲。 我會將輸入檢測保留在Update
內部,並允許玩家從中間從一側跳到另一側,但不會偏離軌道,也不會在跳躍時跳躍。 我還將使用時間而不是速度來控制Lerp
的跳躍,如果您願意,您可以輕松地將其更改為速度。
[SerializeField] private float TimeForJump = 0.25f;
[SerializeField] private float JumpOffset = 2.5f;
// I am assuming your setup for lanes is -1 | 0 | 1
private int lane = 0;
private Coroutine PlayerJumping = null;
void Update()
{
// no need to detect input if we are already jumping
if(PlayerJumping == null)
{
// instead of 'a' and 'd' you can use GetAxis to allow for arrow key and wasd support
// it is also an easy way to determine direction when adding or subtracting for a goal location
float horzInput = Input.GetAxis("Horizontal");
if (horzInput < 0 && lane > -1)
{
PlayerJumping = StartCoroutine(Jump(-1));
lane--;
}
else if(horzInput > 0 && lane < 1)
{
PlayerJumping = StartCoroutine(Jump(1));
lane++;
}
}
// simulating your movement
transform.position = new Vector3(transform.position.x, transform.position.y + 0.1f, transform.position.z);
}
/// <summary>
/// Horizontally have the player jump
/// </summary>
private IEnumerator Jump(float direction)
{
// store our current position
float currentXPos = transform.position.x;
// our goal position
float goalXPos = currentXPos + (direction * JumpOffset);
// timer for how long it has passed since we started the jump
float jumpTimer = 0.0f;
// continue the lerp for the time we have left
while(jumpTimer <= TimeForJump)
{
transform.position = new Vector3(Mathf.Lerp(currentXPos, goalXPos, jumpTimer / TimeForJump), transform.position.y, transform.position.z);
// increment the time that has passed
jumpTimer += Time.deltaTime;
yield return null;
}
// set our position directly in case of floating point errors
transform.position = new Vector3(goalXPos, transform.position.y, transform.position.z);
// set the coroutine to null so we can jump again
PlayerJumping = null;
}
由於我不確定你的實現是如何完成的,所以我對車道和其他一般設置有一些假設。 答案非常通用,因此可以根據您的需要進行調整。 如果您願意,您也可以將輸入交換回GetKeyDown
,我使用它的唯一原因是您可以獲得箭頭鍵和 wasd 輸入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.