Jump to content
Unity Insider Forum

GetAxis - Jitter/Hopfen, wenn beide Achsen gleichzeitig betätigt werden


Steve69
 Share

Recommended Posts

Hallo Leute,

ich brauche mal wieder etwas Hilfe von euch.

Ich versuche mich gerade mal an einem 2D-Spiel, bei dem mein Player durch Gänge läuft und auch Leitern hoch und runtern klettern kann.

Solange mein Player horizontal sich bewegt, habe ich die Eigenschaft Gravity Scale im Rigidbody2D auf 1 gesetzt, damit die Schwerkraft ihn auf dem Boden hält.
Sehr nütlich, wenn er eine Schräge hochläuft.

Damit er eine Leiter hoch und runter klettern kann, schalte ich die Eigenschaft Gravity Scale auf 0, damit die Schwerkraft nicht greift. Ansosnten würde er herunterfallen.

Um meinen Player zu bewegen, verwende ich die GetAxis-Funktionen innerhalb der Update-Funktion.

Sieht dann bei mir so aus. (vereinfacht ausgedrückt. Die Variablen habe ich außerhalb definiert. Sind hier aufgeführt damit ihr seht, worum es sich handelt)
--> die Gravity Scale setze ich an anderer Stelle

            float xDir;
            float yDir;
           
            float hSpeed = 1.0f;
            float vSpeed = 1.0f;
 
            xDir = Input.GetAxis("Horizontal") * hSpeed * Time.deltaTime;
            yDir = Input.GetAxis("Vertical") * vSpeed * Time.deltaTime;
 
            Vector2 moveVector2D = new Vector2(xDir,yDir);
            transform.Translate(moveVector2D);

Das klappt soweit auch, solange ich meine Tasten schön hintereinander betätige.

Um nun beim Hochklettern schnellstmöglich am Ende der Leiter z.B. nach rechts abbiegen zu können, betätige ich kurz vor Ende jetzt beide Achsen gleichzeitig.
Jetzt tritt plötzlich das Phänomen auf, dass mein Player anfängt zu hopfen (Jitter).

Obwohl der moveVector2D im yDir-Wert immer konstant bleibt, verändert sich im Inspector der Y-Wert stetig.

grafik.png.1b4f87cf3f85129f7c055a937d77705d.png

grafik.png.bae1aca4ed7956ac328f1ee8aae2b9ad.png

Da ich dachte, dass das mit der Gravity Scale Einstellung zu tun haben könnte, habe ich den Wert auch beim horizontalen Laufen auf 0 gestellt.

Auch in diesem Zustand "hoppelt" mein Player. Nur etwas wenige hoch.  Echt komisch.

Habt ihr ne Idee, woran das liegen könnte.

Was mache ich da falsch?

 

Im Voraus besten Dank für eure Hilfe.

Gruß

Stephan

 

 

 

 

 

 

 

 

 

 

 

 

Link to comment
Share on other sites

Da sind mehrere Sachen im Spiel.
Einmal, wie du schon gemerkt hast, die Gravity. Die versucht natürlich deinen Körper immer nach unten zu ziehen. Ja und dann der Zeitpunkt wann etwas gemacht wird.

Ich gehe stark davon aus, dass du deinen Player in der Update bewegst. Wenn das so ist, dann hast du das Problem der unterschiedlichen Abarbeitungen in Unty.
Alles Physikalische wird in FixedUpdate Zyklus gemacht und dieser Zyklus ist unabhängig von der Framerate. Er sollte immer konstant passieren.

Die Update wird aber abhängig von deiner Framerate ausgeführt. Und ohne Vsync kann die mächtig schwanken. Selbst wenn sie nicht schwankt, hat sie einen ganz anderen Zyklus als die FixedUpdate.

Wenn jetzt z.B. die Physik 50 mal pro Sekunde berechnet wird, du aber 60 mal pro Sekunde deinen Player bewegst, kommt es zwangsläufig zu sichtbaren hopplern wegen der Schwerkraft.

Das kannst du schon einmal umgehen, indem du die Bewegung in der FixedUpdate machst. Das ist dann zum selben Zeitpunkt wie die physikalische Berechnung.
Jetzt ist all die Bewegung synchron aber nicht synchron mit deiner Framerate. Es könnte sein, dass du auch jetzt noch ein leichtes Ruckel bemerkst.

Es ist immer ein Problem, wenn du Physik, wie die Schwerkraft nutzt, aber die Bewegung des Players durch setzen der Transform machst.

Am besten du nutzt nur ein System. Entweder alles über die Physik, indem du den RB per diverser Befehle eine Bewegung gibst, oder alles ohne Physik, wobei du dann die Schwerkraft selber erzeugst, indem du das per Script mit der Y Achse tust solange du nicht auf einem Boden oder der Leiter stehst.

Machst du alles über die Physik, kannst du ein leichtes Zittern sehen, wenn die Kamera sich mit bewegt. Das ist aber leicht zu verhindern, indem du den RB sagst, dass er die Bewegung interpolieren soll. Schon ist alles schön weich.

Machst du alle ohne Physik, dann sollte auch alles super smooth sein. Die Kamerabewegung sollte dann trotzdem in der LateUpdate bewegt werden, damit wirklich alle anderen Bewegungen vor der Kamera gemacht wurden. Du weisst ja nie, welches Script wann seine Update ausführt. Du hast also keinen Einfluss auf die Reihenfolge.
Natürlich kann man in Unity sagen, welches Script z.B. als aller erstes bearbeitet werden soll, aber viel mehr ist unpraktisch.

Spiel mal ein wenig mit den verschiedenen Funktionen rum. Du wirst die Unterschiede bemerken.

Link to comment
Share on other sites

Hallo Malzbie,

zuerst mal vielen Dank für deine Hilfe.

Habe mir die Sache mal angeschaut und versuche aktuell meinen Code dahingehend zu ändern, dass ich Transform nicht mehr verwende.

Hab auch die Verarbeitung, wie geraten, in die FixedUpdate-Funktion eingebaut.

Mit meiner alten Implementierung (Transform) hatte das keine Auswirkung. Konnte aber den Fehler in meinem Code wiederum dank deiner Anregung finden.

Hatte vor dem eigentlichen Setzen der yDir eine IF-Bedingung (bei der Frage leider nicht ersichtlich), die in bestimmten Fällen diese dann nicht aktualisiert hatte.

Zum Zeitpunkt meiner Anfrage war mir nicht bewußt, dass ich yDir eigentlich auf 0 hätte setzen müssen, anstatt die Aktualisierung einfach zu übergehen.

Durch das Übergehen hat sich Unity, aufgrund dessen, dass ich yDir außerhalb der Update-Funktion deklariert hatte, den Wert natürlich gemerkt. So kam es dann zustande, dass bei jedem Update mein Player zunächst auf den alten yDir Wert gesetzt wurde (also etwas weiter oben) und durch die Schwerkraft dann wieder runterbewegt wurde. Dadurch kam das "hoppeln" zustande.

Nachdem ich dann quasi die Zeile

Vector2 moveVector2D = new Vector2(xDir,yDir);

in

Vector2 moveVector2D = new Vector2(xDir,0);

geändert hatte, war mein Problem gelöst.

Dennoch werde ich die Sache entsprechend so umprogrammieren, dass ich das mit Transform in diesem Fall nicht nutze.

Viele Dank nochmals für die Hilfe und für die tolle Erklärung.

Gruß

Stephan

 

Link to comment
Share on other sites

Gerne! :)

Eine Sache noch, die es dir etwas einfacher macht, wenn du Code im Forum posten willst.

Oben, in der Texteditor Leiste, ist das Symbol  <> . Wenn du da drauf klickst, öffnet sich ein weiteres Fenster, wo du dann unten-rechts das entsprechenden Syntax Highlight auswählen kannst ( da nimmst du einfach C) und dann kopierst du einfach deine Codeschnipsel und fügst sie in dieses Fenster ein.
Schon ist ein gut lesbarer Code im Post zu sehen und du musst nicht immer Screenshots machen, oder Texte einfärben.
So sieht sowas dann aus:

public void Testeintrag(){
  // das ist nur ein Test
  print("das ist nur ein Test");
}

 

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...