2016-08-14 4 views
0

Je travaille sur un jeu de coureur sans fin 3d à 3 voies et je suis tombé sur ce problème. Avec un peu d'aide de ce débordement de pile, j'ai réussi à changer mon personnage dans les 3 couloirs, après quelques secondes mon personnage s'éloigne lentement des couloirs, simplement plutôt que de courir une ligne droite sur chaque couloir. Après avoir basculé le personnage s'éloigne de la voie. C'est vraiment énervant. Comment je le répare? Je suis venu à remarquer que l'axe des x du personnage, les valeurs de points augmente petit à petit. par exemple Si c'est la bonne voie, elle devrait être de 1.0000, mais après la commutation, elle augmente progressivement de 1.0045, 1.0345, 1.09585 etc. et vice versa aussi. Parfois aussi, il casse aussi le mouvement à 3 voies et le personnage essaie de se déplacer complètement vers la droite ou vers la gauche sans s'arrêter, donc je dois arrêter le mode de jeu.Comment changer de ligne avec précision avec mon script?

L'aide serait grandement appréciée.

Voici mon script.

//Variables for Lane switching 
    private bool isChangingLane = false; 
    private Vector3 locationAfterChanginLane = Vector3.zero; 
    private Vector3 sideWayMovementDistance = Vector3.right * 2f; // This might be the case that triggers abnormal movements 
    private float sideWaySpeed = 6f; 

    public enum Lane 
    { 
     Left, 
     Right, 
     Center 
    } 

    public enum MoveDirection 
    { 
     Left, 
     Right, 
     None 
    } 

    Lane currentLane = Lane.Center; 

    void Update() 
    { 
     currentBaseState = anim.GetCurrentAnimatorStateInfo(0); 

     if (controller.isGrounded) 
     { 
      verticalVelocity = -0.5f; 
      if (currentBaseState.fullPathHash == locoState) 
      { 
       if (Input.GetButtonDown("Jump")) 
       { 
        verticalVelocity = 18f; 

        anim.SetBool("Jump", true); 
       } 
       else if (Input.GetKeyDown(KeyCode.S)) 
       { 
        anim.SetBool("Slide", true); 
       } 

      } 

      MoveLeftRight(); // This is the method to move right and left. 

      if (isChangingLane) 
      { 
       if (Math.Abs(transform.position.x - locationAfterChanginLane.x) < 0.1f) 
       { 
        isChangingLane = false; 
        moveVector.x = 0; 
       } 
      } 



     } 
    } 

    private void MoveLeftRight() 
    { 

     MoveDirection requestedMoveDirection = MoveDirection.None; 
     if (Input.GetKeyDown(KeyCode.A) && !isChangingLane) 
     { 
      requestedMoveDirection = MoveDirection.Left; 
      isChangingLane = true; 
     } 
     else if (Input.GetKeyDown(KeyCode.D) && !isChangingLane) 
     { 
      requestedMoveDirection = MoveDirection.Right; 
      isChangingLane = true; 
     } 

     switch (requestedMoveDirection) 
     { 
      case MoveDirection.Right: 
       if (currentLane == Lane.Right) 
       { 
        Debug.Log("Right Lane"); 
        break; //Do nothing when in right lane. 

       } 
       else if (currentLane == Lane.Center) 
       { 
        locationAfterChanginLane = transform.position + sideWayMovementDistance; 
        moveVector.x = +sideWaySpeed; 

        currentLane = Lane.Right; 
        Debug.Log("Center --> Right"); 
       } 
       else if (currentLane == Lane.Left) 
       { 
        locationAfterChanginLane = transform.position + sideWayMovementDistance; 
        moveVector.x = +sideWaySpeed; 

        currentLane = Lane.Center; 
        Debug.Log("Left --> Center"); 
       } 
       break; 
      case MoveDirection.Left: 
       if (currentLane == Lane.Left) 
       { 
        Debug.Log("Left Lane"); 
        break; //Do nothing when in left lane. 
       } 
       else if (currentLane == Lane.Center) 
       { 
        locationAfterChanginLane = transform.position - sideWayMovementDistance; 
        moveVector.x = -sideWaySpeed; 

        currentLane = Lane.Left; 

        Debug.Log("Center --> Left"); 
       } 
       else if (currentLane == Lane.Right) 
       { 
        locationAfterChanginLane = transform.position - sideWayMovementDistance; 
        moveVector.x = -sideWaySpeed; 

        currentLane = Lane.Center; 

        Debug.Log("Right --> Center"); 
       } 
       break; 
     } 
    } 

Répondre

0

Donc, j'ai finalement trouvé ma réponse à la question alors voilà. Le plus simple serait d'utiliser Clamp pour résoudre le problème. Voici ce que j'ai implémenté.

La méthode Clamp dans la fonction Update.

public static float Clamp(float val, float min, float max) 
    { 
     return (val < min) ? min : (val > max) ? max : val; 
    } 

Dans mon MoveLeftRight() menthod,

switch (requestedMoveDirection) 
     { 
      case MoveDirection.Right: 
       if (currentLane == Lane.Right) 
       { 
        break; //Do nothing when in right lane.      
       } 
       else if (currentLane == Lane.Center) 
       { 
        locationAfterChangingLane = transform.position + sideWayMovementDistance; 
        moveVector.x = +sideWaySpeed; 

        locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, RightLaneMin, RightLaneMax); 
        currentLane = Lane.Right; 
       } 
       else if (currentLane == Lane.Left) 
       { 
        locationAfterChangingLane = transform.position + sideWayMovementDistance; 
        moveVector.x = +sideWaySpeed; 

        locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, centerLaneMin, centerLaneMax); 
        currentLane = Lane.Center; 
       } 
       break; 

      case MoveDirection.Left: 
       if (currentLane == Lane.Left) 
       { 
        break; //Do nothing when in left lane. 
       } 
       else if (currentLane == Lane.Center) 
       { 
        locationAfterChangingLane = transform.position - sideWayMovementDistance; 
        moveVector.x = -sideWaySpeed; 

        locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, leftLaneMin, leftLaneMax); 
        currentLane = Lane.Left; 
       } 
       else if (currentLane == Lane.Right) 
       { 
        locationAfterChangingLane = transform.position - sideWayMovementDistance; 
        moveVector.x = -sideWaySpeed; 

        locationAfterChangingLane.x = Clamp(locationAfterChangingLane.x, centerLaneMin, centerLaneMax); 
        currentLane = Lane.Center; 
       } 
       break; 
     } 

Il vous allez. J'espère que cela aide. Merci à tous pour votre aide. Codage heureux.

2

assez simple, dans la section de code où vous vérifiez si la position actuelle de votre personnage est proche de la position finale, définissez également la position finale.

if (Math.Abs(transform.position.x - locationAfterChanginLane.x) < 0.1f) 
{ 
    isChangingLane = false; 
    moveVector.x = 0; 
    transform.position = locationAfterChanginLane; //Add this line 
} 

La raison pour laquelle cela se produit est essentiellement comment fonctionne la fonction Update. La mise à jour de Monobehaviour n'est PAS appelée sur un pas de temps fixe (ce que nous appelons Time.deltaTime). Par conséquent, dans la plupart des cas, la position de votre personnage va dépasser/sous-estimer la valeur finale.

+0

Très bien. Merci. Je vais l'appliquer et voir le lendemain. –

+0

Travaillé bien que mon personnage recule légèrement quand je change de mouvement latéral maintenant. C'est perceptible. Toute idée sur la façon d'arrêter cela. S'il vous plaît veuillez répondre. –

+1

Que voulez-vous dire, déplacer "retour"? Retour vers l'appareil photo, ou vers l'arrière dans la direction où vous avez commencé? –