2017-08-30 4 views
0

Je fais un jeu 2d. Mon problème est que tout en jouant, si le joueur tient le saut et est sous un BoxCollider2D, le joueur ne tombera pas jusqu'à ce qu'ils relâchent le saut.Unité 5: Rigidbody 2d collé au plafond tandis que la vitesse se déplace vers le haut

Mon lecteur GameObject se compose d'un moteur de rendu de sprite, d'un dynamicbody2d dynamique avec gravité et d'un boxcollider2d.

Voici mes scripts de mouvement:

1:

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

public class JumpScript : MonoBehaviour { 

    [Range(1, 10)] 
    public float jumpVelocity; 

    [Range(0,10)] 
    public float speed; 
    private bool jumpQueue = false; 
    private bool boolin=false; 
    void Update() 
    { 

     //Friggin fall, loser 

     //Jumping 
     ///* 
     if (Input.GetButton("Jump")&& GetComponent<Rigidbody2D>    ().velocity.y==0) 
     { 
      GetComponent<Rigidbody2D>().velocity = Vector2.up *  jumpVelocity; 
     } 
     //*/ 
     //jumpQueue? 
     /* 
     if(Input.GetButtonDown("Jump")) 
     { 
      jumpQueue = true; 
     }*/ 
     //Right Movement 
     if (Input.GetKey(KeyCode.D)) 
     { 
      GetComponent<Rigidbody2D>().velocity = new Vector2(1*speed,   GetComponent<Rigidbody2D>().velocity.y); 
      boolin = true; 
     } 
     if(Input.GetKeyUp(KeyCode.D)) 
     { 
      GetComponent<Rigidbody2D>().velocity = new Vector2(0,  GetComponent<Rigidbody2D>().velocity.y); 
      boolin = false; 
     } 
     //Left Movement 
     if (Input.GetKey(KeyCode.A)) 
     { 
      GetComponent<Rigidbody2D>().velocity = new Vector2(-1*speed,  GetComponent<Rigidbody2D>().velocity.y); 
      boolin = true; 
     } 
     if (Input.GetKeyUp(KeyCode.A)) 
     { 
      GetComponent<Rigidbody2D>().velocity = new Vector2(0,  GetComponent<Rigidbody2D>().velocity.y); 
      boolin = false; 
     } 
     //No movement? 
     if (Input.GetKey(KeyCode.D) && Input.GetKey(KeyCode.A)) 
     { 
      GetComponent<Rigidbody2D>().velocity = new Vector2(0,  GetComponent<Rigidbody2D>().velocity.y); 
      boolin = false; 

     } 

     //Time to handle animation, boios. 
     Rigidbody2D rb = GetComponent<Rigidbody2D>(); 

     bool schwomp = false; 
     bool schwift = false; 
     if(rb.velocity.y>0) 
     { 
      schwomp = true; 
     } 
     if(rb.velocity.y<0) 
     { 
      schwift = true; 
     } 
     Animator anim = GetComponent<Animator>(); 
     if (boolin) 
     { 
      anim.SetInteger("Boolin", 1); 
      /*if (!anim.GetBool("expand")) 
      { 
       anim.SetBool("expand", true); 
       anim.Play("running"); 
      }*/ 
     } 
     else 
     { 
      anim.SetInteger("Boolin", 0); 
      /* 
      if(anim.GetBool("expand")) 
      { 
       anim.SetBool("expand", false); 
       anim.Play("Idle"); 
      }*/ 
     } 
     if(schwomp) 
     { 
      //anim.SetInteger("Boolin", 2); 
     } 
     if(schwift) 
     { 
      //anim.SetInteger("Boolin", 3); 
     } 
    } 
} 

using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 

public class BetterJumper: MonoBehaviour {

public float fallMultiplier = 2.5f; 
public float lowJumpMultiplier = 2f; 

Rigidbody2D rb; 

void Awake() 
{ 
    rb = GetComponent<Rigidbody2D>(); 

} 

void Update() 
{ 
    if(rb.velocity.y<0) 
    { 
     rb.velocity += Vector2.up*Physics2D.gravity.y*(fallMultiplier-1)*Time.deltaTime; 

    } 
    else if(rb.velocity.y>0&&!Input.GetButton("Jump")) 
    { 
     rb.velocity += Vector2.up * Physics2D.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime; 
    } 
} 
} 

Merci beaucoup à l'avance!

+0

Veuillez prendre un moment pour formater votre code correctement. – Soviut

+0

Vous avez écrit ce que le problème est, mais n'a pas donné quel est le résultat attendu .... – Programmer

Répondre

3

Vous utilisez Input.GetKey() qui interrogera la clé à chaque image. Cela signifie que de plus en plus de vélocité est ajoutée plus vous maintenez le saut. Vous avez effectivement construit un jetpack plutôt qu'une force de saut.

Vous devez utiliser Input.GetKeyDown() qui ne se déclenchera qu'une fois lorsqu'une touche est enfoncée, puis doit être relâché et pressé à nouveau pour le déclencher de nouveau. Vous devez ensuite appliquer une seule force verticale suffisamment forte en utilisant RigidBody.AddForce() pour que le personnage saute, plutôt que d'ajouter continuellement à la vélocité. En outre, vous devriez vraiment mettre en cache le résultat de votre appel GetComponent<Rigidbody2D>() lorsque le script se réveille ou démarre afin que vous ne l'appeliez pas de façon continue; Chacun de ces appels prend du temps de traitement. En outre, vous devriez utiliser FixedUpdate() pour la physique.

public class ExampleClass : MonoBehaviour { 
    public float thrust; 
    public Rigidbody rb; // make the rigidbody variable available anywhere in the class 

    void Start() { 
     // cache the rigidbody component to the variable once on start 
     rb = GetComponent<Rigidbody>(); 
    } 

    void FixedUpdate() { 
     // use the variable reference from now on rather than making GetComponent calls 
     rb.AddForce(transform.up * thrust); 
    } 
} 
+0

Merci pour l'aide! J'essaierai certainement ceci quand je peux! – TinFellow

0

La réponse de Soviut l'explique assez bien, mais il y a plus que vous devez savoir. Vous manipulez directement la vélocité, ce qui annule l'effet de toutes les forces, y compris la gravité (malgré le fait que vous l'appliquiez manuellement). Voir le documentation. Comme démontré dans la réponse de Soviut, vous devriez appliquer des forces et des impulsions, laissant le moteur physique déterminer la vitesse. La seule fois où vous devez définir la vélocité directement, c'est quand vous construisez une simulation qui a intentionnellement une physique irréaliste (c'est-à-dire des platformers rétro). Même dans ce cas, gardez à l'esprit que cela crée beaucoup plus de travail, parce que vous aurez besoin de prendre en compte chaque petite chose qui crée du mouvement. Cela signifie que vous réessayez essentiellement le moteur physique.

+0

Assez drôle, j'essaie de créer un jeu de plateforme rétro, haha. – TinFellow

+0

Wow comment ironique. En tout cas, vous pouvez obtenir la sensation d'un jeu de plateforme rétro si vous limitez la vélocité maximum et n'abordez pas avec les forces que vous appliquez. Bonne chance. –

+0

C'est plus une solution de contournement qu'une solution que je peux appliquer à d'autres situations. Cependant, j'ai utilisé raycasting pour déterminer si le joueur est à la terre. De cette façon, il saute maintenant seulement s'il est par terre. Merci pour l'aide! – TinFellow