2016-11-13 32 views
2

我在c#中爲玩家移動寫了一個腳本。每當玩家按下A或D時,就會將他/她向左或向右移動12個單位,當玩家按下W或S時,他會上下移動12個單位。我的腳本工作正常,但如果一個人開始一次性發送所有密鑰,它會消失,並且玩家對象不再與該級別一致。我希望腳本檢查在按鍵上執行移動之前是否存在移動。這裏是我的腳本:阻止玩家發送垃圾信息導致故障

void Update() { 

    transform.Translate(Vector3.forward * ForwardSpeed * Time.deltaTime); 

    if (Input.GetKeyDown (KeyCode.A) && side > maxSideLeft) { 
     MoveObjectTo(this.transform, new Vector3(this.transform.position.x - 12, this.transform.position.y, this.transform.position.z + 10), movementSpeed); 
     side -= 1; 
    } else if (Input.GetKeyDown (KeyCode.D) && side < maxSideRight) { 
     MoveObjectTo(this.transform, new Vector3(this.transform.position.x + 12, this.transform.position.y, this.transform.position.z + 10), movementSpeed); 
     side += 1; 
    } 

    if (Input.GetKeyDown (KeyCode.W) && level < maxLevelHeight) { 
     MoveObjectTo(this.transform, new Vector3(this.transform.position.x, this.transform.position.y + 12, this.transform.position.z + 10), movementSpeed); 
     level += 1; 
    } else if (Input.GetKeyDown (KeyCode.S) && level > minLevelHeight) { 
     MoveObjectTo(this.transform, new Vector3(this.transform.position.x, this.transform.position.y - 12, this.transform.position.z + 10), movementSpeed); 
     level -= 1; 
    } 

    if (Input.GetKeyDown (KeyCode.R) || Input.GetKeyDown(KeyCode.Space)) { 
     SceneManager.LoadScene ("Scene1"); 
     Time.timeScale = 1; 
    } 
} 


private void MoveObjectTo(Transform objectToMove, Vector3 targetPosition, float moveSpeed) 
{ 
    StopCoroutine(MoveObject(objectToMove, targetPosition, moveSpeed)); 
    StartCoroutine(MoveObject(objectToMove, targetPosition, moveSpeed)); 
} 

public static IEnumerator MoveObject(Transform objectToMove, Vector3 targetPosition, float moveSpeed) 
{ 
    float currentProgress = 0; 
    Vector3 cashedObjectPosition = objectToMove.transform.position; 

    while (currentProgress <= 1) 
    { 
     currentProgress += moveSpeed * Time.deltaTime; 

     objectToMove.position = Vector3.Lerp(cashedObjectPosition, targetPosition, currentProgress); 

     yield return null; 
    } 
} 

回答

2

你可以使用一個簡單的isMoving變量這一點。如果變量爲true,請勿移動。如果是false,請移動。當協程完成後,運行集isMoving返回到false。此外,我不知道爲什麼MoveObject函數是static。我從中刪除了static關鍵字。

bool isMoving = false; 

void Update() 
{ 

    transform.Translate(Vector3.forward * ForwardSpeed * Time.deltaTime); 

    if (Input.GetKeyDown(KeyCode.A) && side > maxSideLeft) 
    { 
     MoveObjectTo(this.transform, new Vector3(this.transform.position.x - 12, this.transform.position.y, this.transform.position.z + 10), movementSpeed); 
     side -= 1; 
    } 
    else if (Input.GetKeyDown(KeyCode.D) && side < maxSideRight) 
    { 
     MoveObjectTo(this.transform, new Vector3(this.transform.position.x + 12, this.transform.position.y, this.transform.position.z + 10), movementSpeed); 
     side += 1; 
    } 

    if (Input.GetKeyDown(KeyCode.W) && level < maxLevelHeight) 
    { 
     MoveObjectTo(this.transform, new Vector3(this.transform.position.x, this.transform.position.y + 12, this.transform.position.z + 10), movementSpeed); 
     level += 1; 
    } 
    else if (Input.GetKeyDown(KeyCode.S) && level > minLevelHeight) 
    { 
     MoveObjectTo(this.transform, new Vector3(this.transform.position.x, this.transform.position.y - 12, this.transform.position.z + 10), movementSpeed); 
     level -= 1; 
    } 

    if (Input.GetKeyDown(KeyCode.R) || Input.GetKeyDown(KeyCode.Space)) 
    { 
     SceneManager.LoadScene("Scene1"); 
     Time.timeScale = 1; 
    } 
} 


private void MoveObjectTo(Transform objectToMove, Vector3 targetPosition, float moveSpeed) 
{ 
    //Don't do anything Object is already moving 
    if (isMoving) 
    { 
     return; 
    } 
    //If not moving set isMoving to true 
    isMoving = true; 
    StartCoroutine(MoveObject(objectToMove, targetPosition, moveSpeed)); 
} 

public IEnumerator MoveObject(Transform objectToMove, Vector3 targetPosition, float moveSpeed) 
{ 
    float currentProgress = 0; 
    Vector3 cashedObjectPosition = objectToMove.transform.position; 

    while (currentProgress <= 1) 
    { 
     currentProgress += moveSpeed * Time.deltaTime; 

     objectToMove.position = Vector3.Lerp(cashedObjectPosition, targetPosition, currentProgress); 

     yield return null; 
    } 
    //Done moving. Set isMoving to false 
    isMoving = false; 
} 
+0

謝謝你,我只是不知道我應該在哪裏設置布爾值爲主動和錯誤,所以我可以使它工作。 – alexo1001

+0

我做到了。我在回答中只是爲你做了這件事。只需複製並用您的代碼替換它。 – Programmer

+1

是的,我做到了。謝謝。 – alexo1001

0

這聽起來像你要檢查,看看用戶是否已經完成了他們的線性插值lerping一些新的位置之前。在這種情況下,您需要阻止播放器再次移動,直到currentProgress變量等於1.因此,請使用簡單的布爾回調函數,並在回調爲真前阻止調用Corouting。您MoveObject功能:

public static IEnumerator MoveObject(Transform objectToMove, Vector3 targetPosition, float moveSpeed, System.Action<bool> callBack) 
{ 
    float currentProgress = 0; 
    Vector3 cashedObjectPosition = objectToMove.transform.position; 

    while (currentProgress <= 1) 
    { 
     currentProgress += moveSpeed * Time.deltaTime; 

     objectToMove.position = Vector3.Lerp(cashedObjectPosition, targetPosition, currentProgress); 

     yield return null; 

     if (currentProgress >= 1) 
      callBack(true); 
    } 
} 

然後你就可以改變你的MoveObjectTo函數讀取這個回調:

private void MoveObjectTo(Transform objectToMove, Vector3 targetPosition, float moveSpeed) 
{ 
    if (canCallCoroutine) 
    { 
     canCallCoroutine = false; 
     StartCoroutine(MoveObject(objectToMove, targetPosition, moveSpeed, finished => 
      { 
       if (finished != null) 
       { 
        if (finished) 
         canCallCoroutine = true; 
       } 
      })); 
    } 
} 
+0

canCallCoroutine從哪裏來?這是一開始就宣佈的布爾嗎? – alexo1001

+0

是的,它只是一些全局布爾變量。對不起,沒有更清楚 – bpgeck