2016-04-23 7 views
0

Ich mache einen rundenbasierten 2D-Dungeon-Crawler von Topity in Unity mit C#. Ich programmiere gerade den Code für den Fledermaus-Gegner, um dem Spieler zu folgen. Es funktioniert gut bis auf ein seltsames Verhalten. Der Schläger bewegt sich in 2 Richtungen um 2 Blöcke statt in 1 Richtung um 1 Block, aber nur für seine erste Bewegung. Ähnlich der Bewegung, die der Ritter im Schach macht. Bitte helfen Sie mir, dies herauszufinden. Alle und alle Vorschläge geschätzt. Mein Code ist wahrscheinlich schrecklich und übermäßig kompliziert, aber das ist mein erstes Spiel, also sei bitte sanft.Unheimliches Bewegungsverhalten Unity2D C#

Feind Code:

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; 
     }    
    } 

Spielercode:

// 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, die mit Float-Nummern zu tun hatte, es zu vermasseln, aber ich habe seitdem die Sprites skaliert, so kann ich ganze Zahlen verwenden. Diese Frage hat mit meiner schlechten Codierung zu tun, die ich vermute. – oscaro

+0

@JoeBlow Player Bewegung ist jetzt perfekt – oscaro

Antwort

3

Gibt es eine Chance, dass Ihr Problem ist, sollten Sie abtrünnigen Code verwenden und Sie nicht? Ihr Code ist wie folgt:

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 
    }  

    } 
} 

In der Tat, sollte es so sein?

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; 
    }  

    } 
} 

Ich schlage vor, das zu versuchen.


Hinweis, Sie müssen wirklich einige Funktionen einführen, um Ihren Code zu vereinfachen. Ihr Code Durchgang wie dieser ...

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

sollte eine Funktion mehr so ​​aussehen:

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

Sie wäre es dann mit ein bisschen wie diese. Sie hätten eine Variable "possibleNewPosition". Sie würden sagen ...

possibleNewPosition = currentPosition + 1; if (IsThisAWall (possibleNewPosition)) Debug.Log ("nichts tun, da es eine Wand ist"); sonst currentPosition = possibleNewPosition;

Es ist sehr üblich, dass Sie das tun, Sie haben eine Variable "möglich ..." etwas oder anderes!

Sie müssen dies wirklich rechtzeitig tun. (Vergessen Sie nicht beim Programmieren, keine Routine sollte jemals länger sein als 5 oder 6 Zeilen Code. Ihre Movement usw. Anrufe sind enorm zu lang.)

@
+0

Ich habe statische verwendet, wie ich dachte, das war, wie Sie andere Skripte Zugriff auf die Variablen lassen würde? Wie würde ich zulassen, dass Bat.cs und Player.cs mit der timeToMove-Variablen interagieren? EDIT: Entschuldigung, ich denke ich sehe jetzt was du meintest. – oscaro

+0

Entschuldigung. Vielen Dank. – oscaro

+0

Verwendet den öffentlichen Player thePlayer; besser als public GameObject playerObject ;? – oscaro