2014-07-09 60 views
2

我想在Unity中製作一個簡單的2D自上而下射手。我有鼠標的基本動作和跟隨,但運動中存在問題。無論何時按下Up和Right的同時,它都會像您期望的那樣沿對角方向移動,但是當您放開Up鍵時,它會沿着對角線方向繼續向右移動。我處理的運動代碼爲:統一2D自上而下射手運動問題C#

void Update() { 
    if(Input.GetKey(Up)){ 
     Debug.Log("UP"); 
     Vector3 velUp = rigidbody2D.velocity; 
     velUp.y = walkSpeed; 
     rigidbody2D.velocity = velUp; 
    } 
    else if(Input.GetKey(Down)){ 
     Vector3 velDown = rigidbody2D.velocity; 
     velDown.y = walkSpeed*-1; 
     rigidbody2D.velocity = velDown; 
    } 
    else if(Input.GetKey(Left)){ 
     Vector3 velLeft = rigidbody2D.velocity; 
     velLeft.x = walkSpeed*-1; 
     rigidbody2D.velocity = velLeft; 

    } 
    else if(Input.GetKey(Right)){ 
     Vector3 velRight = rigidbody2D.velocity; 
     velRight.x = walkSpeed; 
     rigidbody2D.velocity = velRight; 
    } 
    else{ 
     Vector3 velStop = rigidbody2D.velocity; 
     velStop.x = 0; 
     velStop.y = 0; 
     rigidbody2D.velocity = velStop; 
    } 

    //rotation 
    Vector3 mousePos = Input.mousePosition; 

    Vector3 objectPos = Camera.main.WorldToScreenPoint (transform.position); 
    mousePos.x = mousePos.x - objectPos.x; 
    mousePos.y = mousePos.y - objectPos.y; 

    float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg; 
    transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle)); 
} 

我怎樣才能獲得的運動表現正如我所說?隨着它像對角線移動一樣,這使得運動看起來不錯。 任何幫助,不勝感激。謝謝。

回答

6

您以0的速度開始,然後您將所有的移動方向加起來。然後,您將矢量歸一化並將其縮放到您的移動速度。否則,如果步行對角線,則玩家移動得更快。

我沒有檢查的代碼,但這樣的事情會做:

void Update() { 
    Vector3 vel = new Vector3(); 

    if(Input.GetKey(Up)){ 
     Debug.Log("UP"); 
     Vector3 velUp = new Vector3(); 
     // just use 1 to set the direction. 
     velUp.y = 1; 
     vel += velUp; 
    } 
    else if(Input.GetKey(Down)){ 
     Vector3 velDown = new Vector3(); 
     velDown.y = -1; 
     vel += velDown; 
    } 

    // no else here. Combinations of up/down and left/right are fine. 
    if(Input.GetKey(Left)){ 
     Vector3 velLeft = new Vector3(); 
     velLeft.x = -1; 
     vel += velLeft; 
    } 
    else if(Input.GetKey(Right)){ 
     Vector3 velRight = new Vector3(); 
     velRight.x = 1; 
     vel += velRight; 
    } 

    // check if player wants to move at all. Don't check exactly for 0 to avoid rounding errors 
    // (magnitude will be 0, 1 or sqrt(2) here) 
    if (vel.magnitude > 0.001) { 
     Vector3.Normalize(vel); 
     vel *= walkSpeed; 
     rigidbody2D.velocity = vel; 
    } 

    //rotation 
    Vector3 mousePos = Input.mousePosition; 

    Vector3 objectPos = Camera.main.WorldToScreenPoint (transform.position); 
    mousePos.x = mousePos.x - objectPos.x; 
    mousePos.y = mousePos.y - objectPos.y; 

    float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg; 
    transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle)); 
} 

關於Normalize看看這個圖片。

Vector addition

如果你走在只有向上或右邊,你會用速度1移動(我們將在後面乘用你想要的速度)。但是如果你步行對角線,你就會以大約1.4倍的速度行走(綠色矢量)。 Normalize保持矢量的方向不變,但會給出1(紅色矢量)的長度(也稱爲「幅度」)。

在較老的射手中,您可能會發現一個名爲"bunny hopping"的錯誤。我不確定這是否是問題的根源,但我猜想是這樣。

關於vel.magnitude > 0.001

實際上,我們想知道,如果vel.magnitude > 0。但是vel.magnitude是計算結果,因此可能包含舍入誤差。如果您使用浮點值,請始終記住這一點。檢查本身完成是因爲Normalize方法需要除以大小和除以零是邪惡的。不知道如果Normalize本身檢查。

+0

這完美!謝謝。如果你解釋了最後一部分,它會好嗎?我對整體和C#都很陌生,我不太瞭解'vel.magnitude'和'Normalize'部分。 –

+0

'vel.magnitude'獲取速度的「大小」。如果你的速度是(1,1),那麼'幅度'將會是〜1.4(正如梅內所說的「兔子跳躍」問題)。這是基本的三角函數(Sin(ang)= 1/hyp)。 'Normalize'減少了一個矢量,使它的最大分量是1.也就是說, (2,4)將歸一化爲(0.5,1) – anothershrubery

+0

這是不正確的。 'Normalize'會給你一個大小爲1的矢量。 – Mene

0

這似乎是你唯一一次強制你的速度沒有任何按鍵被按下的時候。

我可能會建議增加一些檢查時看到Input.GetKeyUptrue,並設置rigidbody2D.velocityxy0,也許是這樣的:

void Update() { 

    if (Input.GetKeyUp(Up) || Input.GetKeyUp(Down)) { 
     rigidbody2D.velocity.y = 0; 
    } 

    if (Input.GetKeyUp(Left) || Input.GetKeyUp(Right)) { 
     rigidbody2D.velocity.x = 0; 
    } 

    ...