Jump to content
Unity Insider Forum

Springen und Joystick funktioniert nicht


Thanny08
 Share

Recommended Posts

Moin Moin,

 

Ich habe ein Problemchen mit meinem Joystick und dem Springen.

Den Joystick kann ich wie ich will benutzen (nur auf der x Achse), aber dann funktionier meine JumpFunktion plötzlich nicht mehr. Wenn ich die Joystick funktionen komplett entferne, so funktioniert das springen wieder. Scheint als würde Der Joystick das springen verhindern. Müsste demnach ein Fehler im Script sein. Habe troz langem Suchen nichts gefunden.

Hier mein Script:

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
using UnityEngine.UI;


public class Player : MonoBehaviour                      //Player Bewegung und Springen inkl Richtugswechsel und ähnliches
{

    public float jumpForce = 10;                                 //Sprungstärke deklarieren
    private Rigidbody2D rb;                         //Den Rigidbody des Players bekommen
    private bool canJump;                                        //Darf Player springen?
    bool buttonHeldDown;                                   //Den Animator des Players für die Jump Animation
    public int RespawnPlayer;

    public MovementJoystick movementJoystick;
    public float playerSpeed;

    private void Start()
    {

        rb = GetComponent<Rigidbody2D>();           //Player  Rigidbody wird deklariert
    }


    void FixedUpdate()
    {
        if (movementJoystick.joystickVec.x != 0)
        {
            rb.velocity = new Vector2(movementJoystick.joystickVec.x * playerSpeed, 0);
        }
        else
        {
            rb.velocity = Vector2.zero;
        }
    }

    public void HoldButton()                                     //Hold Methode für den Button => button wird gedrückt
    {
        buttonHeldDown = true;                                   //Player springt
    }
    public void ReleaseButton()                                  //Hold Methode für den Button => button wurde losgelassen
    {
        buttonHeldDown = false;                                  //Player springt nicht mehr

    }
    void OnCollisionEnter2D(Collision2D collision)               //Berührt der Player den Boden?
    {
        canJump = true;                                          //Wenn er den Boden berührt, darf er springen
    }


    private void Update()                                        //Die Bewegung und Das Springen
    {




        //Das Springen

        if (buttonHeldDown)                                      //Wenn Button gedrückt wird
        {

            while (canJump)                                      //wenn der Player springen Darf (Die While-Schleife wiedrholt sich ständig
            {
                if (canJump)
                {
                    canJump = false;                             // Player darf nicht mehr springen (er soll ja nicht in der Luft springen können)

                    rb.velocity = new Vector2(0f, jumpForce); //Neue Kraft (Das Springen) 

                    //playerAnimator.SetTrigger("JumpTrigger");   //Der Trigger für die Jump Anim wird gesetzt


                }
            }
        }
    }
    private void OnTriggerEnter2D(Collider2D other)             //Respawn des Players
    {
        if (other.CompareTag("Respawn"))                            //Wenn Collider Den Tag "Tod" hat
        {

            SceneManager.LoadScene(RespawnPlayer);              
        }


    }
}

Vieleicht kann mir ja jemand helfen... 

 

LG

Link to comment
Share on other sites

vor 3 Stunden schrieb Thanny08:
 while (canJump)                                      //wenn der Player springen Darf (Die While-Schleife wiedrholt sich ständig
            {
                if (canJump)
                {
                    canJump = false;                             // Player darf nicht mehr springen (er soll ja nicht in der Luft springen können)

                    rb.velocity = new Vector2(0f, jumpForce); //Neue Kraft (Das Springen) 

                    //playerAnimator.SetTrigger("JumpTrigger");   //Der Trigger für die Jump Anim wird gesetzt


                }
            }

Erstmal zum While:
Sobald die Schleife ausgeführt wird ( weil canJump true ist), wird gleich darunter abgefragt, ob canJump true ist. Und wenn ja ( ist ja, sonst wären wir nicht in der Schleife), dann wird es sofort auf false gesetzt.
Somit ist die Schleife unnütz, denn sie wird immer nach einem Durchlauf beendet.

In diesem Bereich "setzt" du die Velocity fürs Springen.  Gleichzeitig setzt du die Bewegungs Velocity auf 0. Soll das so sein, dass er beim Springen nur senkrecht nach oben hüpft?

vor 3 Stunden schrieb Thanny08:
void FixedUpdate()
    {
        if (movementJoystick.joystickVec.x != 0)
        {
            rb.velocity = new Vector2(movementJoystick.joystickVec.x * playerSpeed, 0);
        }
        else
        {
            rb.velocity = Vector2.zero;
        }
    }

In der FixedUpdate fragst du den Joystick ab und "setzt" wieder eine Velocity. Diesmal bekommt die x Achse einen wert und die Y Achse wird 0 !
Wird der Joystick nicht bewegt, dann setzt du beide Achsen auf 0, denn genau das bedeutet Vector2.zero.
Solltest du gerade die Velocity fürs Springen gesetzt haben, wird sie hier auf 0 gesetzt. Egal ob du den Joystick bewegt hast oder nicht.

Am Besten du setzt eine Vector2 Variable mit den RB Velocities die er gerade hat und änderst dann diese Variable auf der entsprechenden Achse ab.
Dann nutzt du die veränderte Variable und übergibst sie dem RB.
So etwa:
 

void FixedUpdate(){
  Vector2 isVelocity = rb.velocity; // Hilfsvarable mit Werten vom rb füllen
  if(movementJoystick.joysticVex.x !=0){ // wenn was am Joystick passiert dann...
    isVelocity.x = movementJoystick.x * playerSpeed; //nur den x-Wert der Variable überschreiben
  }
  if(buttonHeldDown && canJump){ // wenn der Button gedruckt ist und ich auch hüpfen darf...
    isVelocity.y = jumpForce; // nur den y-Wert der Variable überschreiben
    canJump= false; 
  }
  rb.velocity= isVelocity; // der RB bekommt jetzt die neuen Werte komplett übergeben. Wurde kein Wert überschrieben, bekommt er die ausgelesenen Werte zurück
}


FixedUpdate und Update laufen zu unterschiedlichen Zyklen ab. Die Update macht das bei jedem Frame und die Fixed Update nach einer eingestellten Zeit.

Das ist also so gut wie niemals zur selben Zeit. Man sollte alle Dinge die einen RB betreffen, egal ob du die Velocity setzt oder die Force addierst, in der FixedUpdate machen, damit das Ganze synchron mit allen anderen physikalischen Dingen wie Collidern oder Triggern oder der Schwerkraft passiert.

Deswegen hab ich dir in meinem Beispiel alles in die FixedUpdate gepackt. :)

 

Link to comment
Share on other sites

Vielen Vielen Dank für die schnelle Ausführliche Antwort und Erklärung!

 

vor 6 Stunden schrieb malzbie:
isVelocity.x = movementJoystick.x * playerSpeed; //nur den x-Wert der Variable überschreiben

                                                                         ^

 Jedoch zeigt es mir bei dem x bei movementJoystick einen Fehler an, aus dem ich troz übersetzen nicht schlau geworden bin...

Assets\C# SCRIPTS\Player.cs(33,45): error CS1061: 'MovementJoystick' does not contain a definition for 'x' and no accessible extension method 'x' accepting a first argument of type 'MovementJoystick' could be found (are you missing a using directive or an assembly reference?)                                                                        

Link to comment
Share on other sites

vor 10 Stunden schrieb Thanny08:
movementJoystick.joystickVec.x

Ja.... ich habe das nicht richtig abgeschrieben, Aber weisst ja wie es wirklich heisst. Nämlich so wie in dem Zitat. ;)

Wenn jemand einen Codevorschlag postet, so wie ich das getan habe, dann reicht es nicht ihn einfach zu kopieren. Du muss schon mitdenken, denn ich habe den Code nicht getestet. Ich habe dir einfach eine Möglichkeit gezeigt und deswegen dazu geschrieben ":

 

vor 7 Stunden schrieb malzbie:

So etwa:

Du schaffst das! :)
 

Link to comment
Share on other sites

Hat jetz alles bestens geklappt und bin mega happy 😁

Jetzt als ,,Gutes " funktionierendes Script nochmal für alle die Sowas brauchen:

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
using UnityEngine.UI;


public class Player : MonoBehaviour                      //Player Bewegung und Springen inkl Richtugswechsel und ähnliches
{

    public float jumpForce = 10;                                 //Sprungstärke deklarieren
    private Rigidbody2D rb;                         //Den Rigidbody des Players bekommen
    private bool canJump;                                        //Darf Player springen?
    bool buttonHeldDown;                                   //Den Animator des Players für die Jump Animation
    public int RespawnPlayer;

    public MovementJoystick movementJoystick;            //Man braucht ein Panel(Bereich wo der joystick benutzt werden kann) mit 2 Images Die der innerer(Joystick) und äussere Teil des Joystick(JoystickBG) sind movementJoystick ist hier das komplette Panel:
    public float playerSpeed;

    private void Start()
    {
        
        rb = GetComponent<Rigidbody2D>();           //Player  Rigidbody wird deklariert
    }


    void FixedUpdate()
    {
        Vector2 isVelocity = rb.velocity; // Hilfsvarable mit Werten vom rb füllen
        if (movementJoystick.joystickVec.x != 0)
        { // wenn was am Joystick passiert dann...
            isVelocity.x = movementJoystick.joystickVec.x * playerSpeed; //nur den x-Wert der Variable überschreiben
        }
        if (buttonHeldDown && canJump)
        { // wenn der Button gedruckt ist und ich auch hüpfen darf...
            isVelocity.y = jumpForce; // nur den y-Wert der Variable überschreiben
            canJump = false;
        }
        rb.velocity = isVelocity; // der RB bekommt jetzt die neuen Werte komplett übergeben. Wurde kein Wert überschrieben, bekommt er die ausgelesenen Werte zurück
    }
    public void HoldButton()                                     //Hold Methode für den Button => button wird gedrückt
    {
        buttonHeldDown = true;                                   //Player springt
    }
    public void ReleaseButton()                                  //Hold Methode für den Button => button wurde losgelassen
    {
        buttonHeldDown = false;                                  //Player springt nicht mehr

    }
    void OnCollisionEnter2D(Collision2D collision)               //Berührt der Player den Boden?
    {
        canJump = true;                                          //Wenn er den Boden berührt, darf er springen
    }


    private void OnTriggerEnter2D(Collider2D other)             //Respawn des Players
    {
        if (other.CompareTag("Respawn"))                            //Wenn Collider Den Tag "Tod" hat
        {

            SceneManager.LoadScene(RespawnPlayer);
        }


    }
}

Nochmal vielen vielen dank an @malzbie !!!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...