2016-11-13 5 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であれば移動してください。コルーチンが終了したら、isMovingfalseに戻して実行します。また、なぜ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前にlerpを完了したかどうかを確認したいようですね。その場合、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

関連する問題