2016-04-23 7 views
0

私はUnityでC#でターンベースのトップダウンの2Dダンジョンクローラーを作っています。私は現在、バットの敵がプレイヤーに従うようにコードをプログラミングしています。 1つの奇妙な動作を除いてうまくいきます。バットは1方向ではなく2方向に1ブロック移動しますが、それは最初の動きだけです。騎士がチェスの動きに似ています。これを理解するのを助けてください。すべての提案が高く評価されました。私のコードはおそらくひどくひどく複雑ですが、これは私の最初のゲームですので、優しくしてください。奇妙な動きの振る舞いUnity2D C#

敵コード:

Vector3 currentPosition; 
Vector3 nextPosition; 
public GameObject playerObject; 
public Transform[] wallArray; 
bool canMove; 
public Player thePlayer; 

void Update() 
{ 
    currentPosition = transform.position; 
    Movement();  
} 

void Movement() 
{ 
    if (thePlayer.timeToMove == false) 
    { 
     if (playerObject.transform.position.x > currentPosition.x) 
     { 
      nextPosition.x = currentPosition.x + 1; 
      canMove = false; 
      foreach (Transform wall in wallArray) 
      { 
       if (wall.transform.position.Equals(nextPosition)) 
       { 
        nextPosition = currentPosition; 
        canMove = true; 
       } 
      } 

      if (canMove) 
      { 
       if (playerObject.transform.position.y > currentPosition.y) 
       { 
        nextPosition.y = currentPosition.y + 1; 
        foreach (Transform wall in wallArray) 
        { 
         if (wall.transform.position.Equals(nextPosition)) 
         { 
          nextPosition = currentPosition; 
         } 
        } 
       } 

       if (playerObject.transform.position.y < currentPosition.y) 
       { 
        nextPosition.y = currentPosition.y - 1; 
        foreach (Transform wall in wallArray) 
        { 
         if (wall.transform.position.Equals(nextPosition)) 
         { 
          nextPosition = currentPosition; 
         } 
        } 
       } 
      } 
      if (nextPosition == playerObject.transform.position) 
      { 
       nextPosition = currentPosition; 
      } 
      transform.position = nextPosition; 
      thePlayer.timeToMove = true; 
      Debug.Log("Leaving 'a'..."); 
      return; 
     } 

     if (playerObject.transform.position.x < currentPosition.x) 
     { 
      nextPosition.x = currentPosition.x - 1; 
      canMove = false; 
      foreach (Transform wall in wallArray) 
      { 
       if (wall.transform.position.Equals(nextPosition)) 
       { 
        nextPosition = currentPosition; 
        canMove = true; 
       } 
      } 
      if (canMove) 
      { 
       if (playerObject.transform.position.y > currentPosition.y) 
       { 
        nextPosition.y = currentPosition.y + 1; 
        foreach (Transform wall in wallArray) 
        { 
         if (wall.transform.position.Equals(nextPosition)) 
         { 
          nextPosition = currentPosition; 
         } 
        } 
       } 

       if (playerObject.transform.position.y < currentPosition.y) 
       { 
        nextPosition.y = currentPosition.y - 1; 
        foreach (Transform wall in wallArray) 
        { 
         if (wall.transform.position.Equals(nextPosition)) 
         { 
          nextPosition = currentPosition; 
         } 
        } 
       } 
      } 
      if (nextPosition == playerObject.transform.position) 
      { 
       nextPosition = currentPosition; 
      } 
      transform.position = nextPosition; 
      thePlayer.timeToMove = true; 
      Debug.Log("Leaving 'b'..."); 
      return; 
     } 

     if (playerObject.transform.position.x == currentPosition.x) 
     { 
      if (playerObject.transform.position.y > currentPosition.y) 
      { 
       nextPosition.y = currentPosition.y + 1; 
       foreach (Transform wall in wallArray) 
       { 
        if (wall.transform.position.Equals(nextPosition)) 
        { 
         nextPosition = currentPosition; 
        } 
       } 
      } 

      if (playerObject.transform.position.y < currentPosition.y) 
      { 
       nextPosition.y = currentPosition.y - 1; 
       foreach (Transform wall in wallArray) 
       { 
        if (wall.transform.position.Equals(nextPosition)) 
        { 
         nextPosition = currentPosition; 
        } 
       } 
      } 
      if (nextPosition == playerObject.transform.position) 
      { 
       nextPosition = currentPosition; 
      } 
      transform.position = nextPosition; 
      thePlayer.timeToMove = true; 
      Debug.Log("Leaving 'c'..."); 
      return; 
     }    
    } 

プレーヤーコード:

// Movement variables 
public Vector3 playerCurrentPosition; 
Vector3 nextPosition; 
public Transform[] wallArray; 
public bool timeToMove; 
bool movingToWall; 

void Start() 
{ 
    // When we start we can move 
    timeToMove = true; 
} 

void Update() 
{ 
    // Update current position variable 
    playerCurrentPosition = transform.position; 
    // Move 
    Movement(); 
} 

// Movement 
void Movement() 
{ 
    // If it's time to move 
    if (timeToMove) 
    { 
     // If right arrow key pressed 
     if (Input.GetKeyDown(KeyCode.RightArrow)) 
     { 
      // Set position to move to 
      nextPosition.x = playerCurrentPosition.x + 1; 
      // Check wall array 
      foreach (Transform wall in wallArray) 
      { 
       // If the wall we are checking is in the space we want to move to 
       if (wall.transform.position.Equals(nextPosition)) 
       { 
        // We are moving into a wall 
        movingToWall = true; 
       } 
      } 

      // If we are moving into a wall 
      if (movingToWall) 
      { 
       // Don't move 
       nextPosition = playerCurrentPosition; 
       // Set position 
       transform.position = nextPosition; 
       // It's time to move again 
       timeToMove = true; 
       // We're not moving into a wall anymore 
       movingToWall = false; 
      } 
      // If we're not moving into a wall 
      else 
      { 
       // Move 
       transform.position = nextPosition; 
       // It's no longer time to move 
       timeToMove = false; 
      }    
     } 
     // If left arrow key pressed 
     if (Input.GetKeyDown(KeyCode.LeftArrow)) 
     { 
      // Set position we want to move to 
      nextPosition.x = playerCurrentPosition.x - 1; 
      // Check wall array 
      foreach (Transform wall in wallArray) 
      { 
       // If the wall we are checking is in the space we want to move to 
       if (wall.transform.position.Equals(nextPosition)) 
       { 
        // We are moving into a wall 
        movingToWall = true; 
       } 
      } 
      // If we are moving into a wall 
      if (movingToWall) 
      { 
       // Don't move 
       nextPosition = playerCurrentPosition; 
       // Set position 
       transform.position = nextPosition; 
       // We can move again 
       timeToMove = true; 
       // We are no longer moving into a wall 
       movingToWall = false; 
      } 
      // If we are not moving into a wall 
      else 
      { 
       // Move 
       transform.position = nextPosition; 
       // It is no longer time to move 
       timeToMove = false; 
      } 
     } 
     // If up arrow pressed 
     if (Input.GetKeyDown(KeyCode.UpArrow)) 
     { 
      // Set position to move to 
      nextPosition.y = playerCurrentPosition.y + 1; 
      // Check wall array 
      foreach (Transform wall in wallArray) 
      { 
       // If wall we are checking is in space we want to move to 
       if (wall.transform.position.Equals(nextPosition)) 
       { 
        // We are moving into a wall 
        movingToWall = true; 
       } 
      } 
      // If we are moving into a wall 
      if (movingToWall) 
      { 
       // Don't move 
       nextPosition = playerCurrentPosition; 
       // Set position 
       transform.position = nextPosition; 
       // We can move again 
       timeToMove = true; 
       // No longer moving into wall 
       movingToWall = false; 
      } 
      // If we are not moving into a wall 
      else 
      { 
       // Move 
       transform.position = nextPosition; 
       // It is no longer time to move 
       timeToMove = false; 
      } 
     } 
     // If down arrow pressed 
     if (Input.GetKeyDown(KeyCode.DownArrow)) 
     { 
      // Set position to move to 
      nextPosition.y = playerCurrentPosition.y - 1; 
      // Check wall array 
      foreach (Transform wall in wallArray) 
      { 
       // If wall we are checking is in the space we want to move to 
       if (wall.transform.position.Equals(nextPosition)) 
       { 
        // We are moving into a wall 
        movingToWall = true; 
       } 
      } 
      // If we are moving into a wall 
      if (movingToWall) 
      { 
       // Don't move 
       nextPosition = playerCurrentPosition; 
       // Set position 
       transform.position = nextPosition; 
       // We can move again 
       timeToMove = true; 
       // No longer moving into a wall 
       movingToWall = false; 
      } 
      // If we are not moving into a wall 
      else 
      { 
       // Move 
       transform.position = nextPosition; 
       // No longer time to move 
       timeToMove = false; 
      } 
     } 
    }  
} 
+0

@JoeBlowは浮動小数点数を混乱させていましたが、私は私は整数を使用できるようにスプライトをスケールアップして以来。この質問は私が想定している貧弱なコーディングと関係がある。 – oscaro

+0

@JoeBlowプレーヤーの動きは今すぐ完璧です – oscaro

答えて

3

はあなたの問題がある可能性があり、あなたは離脱コードを使用する必要があり、あなたではありませんか?あなたのコードは次のようになります:

void Movement() 
{ 
if (Player.timeToMove == false) 
    { 
    if (playerObject.transform.position.x > currentPosition.x) 
    { 
    // huge amount of code 
    } 

    if (playerObject.transform.position.x < currentPosition.x) 
    { 
    // huge amount of code 
    } 

    if (playerObject.transform.position.x == currentPosition.x) 
    { 
    // huge amount of code 
    }  

    } 
} 

実際、このようにする必要がありますか?

void Movement() 
{ 
if (Player.timeToMove == false) 
    { 
    if (playerObject.transform.position.x > currentPosition.x) 
    { 
    // huge amount of code 
    Debug.Log("Leaving 'a'..."); 
    return; 
    } 

    if (playerObject.transform.position.x < currentPosition.x) 
    { 
    // huge amount of code 
    Debug.Log("Leaving 'b'..."); 
    return; 
    } 

    if (playerObject.transform.position.x == currentPosition.x) 
    { 
    // huge amount of code 
    Debug.Log("Leaving 'c'..."); 
    return; 
    }  

    } 
} 

私はそれを試みることをお勧めします。


実際、コードを単純化するためにいくつかの関数を導入する必要があります。

private bool IsThisAWall(Vector3 p) 
    { 
    foreach (Transform wall in wallArray) 
    if (wall.transform.position.Equals(p)) 
     { 
     return true; 
     } 
    return false; 
    } 

あなたは、このようにソートのそれを使用します。このようなあなたのコード通路...

foreach (Transform wall in wallArray) 
    if (wall.transform.position.Equals(nextPosition)) 
     { 
     movingToWall = true; 
     } 

は、より多くのこのような関数でなければなりません。あなたは変数 "possibleNewPosition"を持っています。あなたは言うだろう...

可能な新しい位置[現在の位置+ 1; if(IsThisAWall(possibleNewPosition)) Debug.Log(「壁のため何もしない」); else currentPosition = possibleNewPosition;

これは非常に一般的なことですが、変数「可能な...」などがあります。

本当にこれを行う必要があります。あなたのMovementなどの呼び出しは非常に長いです。)

+0

これは、他のスクリプトが変数にアクセスできるようにする方法だと思ったので、私は静的を使用しましたか? Bat.csとPlayer.csが両方ともtimeToMove変数とやり取りすることを許可するにはどうすればよいですか?編集:申し訳ありませんが、私は今あなたが意味していたと思う。 – oscaro

+0

申し訳ありません。ありがとうございました。 – oscaro

+0

PublicプレーヤーthePlayerを使用しています。パブリックGameObject playerObjectよりも優れています; – oscaro