2016-11-13 67 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