Warum bleibt Unity Eventsystem bei der ersten Berührung zurück?

7

Hallo, ich mache ein sehr einfaches Platformer-Spiel für Android-Geräte. Ich benutze das Ereignissystem von Unity für Spielerbewegungen. Das Problem ist, wenn ich den Knopf zum ersten Mal berührte, gab es eine Verzögerung (Schluckauf), danach ist alles in Ordnung. Ich habe mein Spiel profiliert, da die EventSystem Update-Methode einen Spitzenwert aufweist.

Hier ist der vereinfachte Code.

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

[RequireComponent (typeof(Rigidbody2D)) ]   
[RequireComponent (typeof(BoxCollider2D)) ]
public class PlayerController : MonoBehaviour {


public float movementSpeed = 5f;
public float jumpForce = 5f;
public float distanceToGround = 0.2f;
public LayerMask staticCollider;
public playerState state;

private Rigidbody2D rBody;
public Transform leftmost;
public Transform rightmost;

Collider2D[] platforms = new Collider2D[2];
public int hrInput = 0;

// Use this for initialization
void Start ( ) {
    rBody = GetComponent<Rigidbody2D> ();

}


//FixedUpdate is framerate independent, and therefore completely unrelated to your framerate

void FixedUpdate ()
{
    state.grounded = isGrounded ();


    if (hrInput > 0) {
        MOVE_RIGHT ();
    }
    else if (hrInput < 0) {
        MOVE_LEFT ();
    } else {
        STOP_MOVE ();

    }

}

public bool isGrounded(){
    print ("ground");
    if (Physics2D.OverlapAreaNonAlloc (leftmost.position, rightmost.position, platforms, staticCollider) > 0) {
        return true;
    } else
        return false;
}


public void setHrInput (int h ) {
//    print (h);

    hrInput = h;
}

public void JUMP(){
    if(state.grounded){
        state.onAir = true;
      //  rBody.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
        rBody.velocity = Vector2.up * jumpForce;
    }
}

public void MOVE_LEFT(){
    rBody.velocity = new Vector2 (-1 * movementSpeed * Time.deltaTime, rBody.velocity.y);
}

public void MOVE_RIGHT(){
    rBody.velocity = new Vector2(1 * movementSpeed*Time.deltaTime, rBody.velocity.y);
}

public void STOP_MOVE(){
    rBody.velocity = new Vector2(0,rBody.velocity.y);
    }

} // end 

Hier ist das Profiler-Image.

Geben Sie hier die Bildbeschreibung ein

Bitte helfen Sie mir, dieses Problem zu beheben.

Shohanur Rahaman
quelle
1
Das ist eigentlich eine gute Frage. Ich erlebe immer das Gleiche, egal wie groß das Spiel ist oO
Jacob
Welche Taste bleibt beim ersten Drücken zurück, alle oder nur eine, oder bleibt das Spiel bei der ersten Berührungseingabe zurück, unabhängig von der Taste? Außerdem wäre es hilfreich, die Verzögerungsspitze des Profilers zu sehen und festzustellen, welche Ereignisse wie viel Zeit in diesem Frame verbrauchen.
John Hamilton
alle, ok ich lade den Profiler-Screenshot hoch.
Shohanur Rahaman
Screenshot ist nicht besonders hilfreich. Sie sehen dort ziemlich solide 100 fps. Das ist schnell. Der unterstrichene Teil von 4,6 kb ist Garbage Collection und das ist ziemlich minimal.
Draco18s vertraut SE am
1
Es hilft nicht, dass Ihr Code nichts mit dem Ereignissystem oder dem Problem zu tun hat, das Sie lösen möchten. Können Sie Ihr Beispiel so ändern, dass es nichts enthält, was nicht mit dem Problem der ersten Berührung zusammenhängt?
Danny Yaroslavski

Antworten:

1

Die Berührungseingabe ist immer eine Art PITA (ich empfehle das InControl-Paket tatsächlich / bin ohnehin nicht angeschlossen), unabhängig davon, ob das Hauptproblem bei Ihnen darin besteht, dass Sie in FixedUpdate nach Eingaben suchen. Die Eingabe sollte in Update überprüft werden. FixedUpdate dient zum Aktualisieren von physischen Körpern. https://docs.unity3d.com/Manual/ExecutionOrder.html

Robert French
quelle
1
Die Vorstellung, dass die Eingabe nur in Update überprüft werden sollte, ist ebenfalls fraglich. Die Unity-Dokumente erwähnen es zwar, aber ihre Beschreibung stimmt nicht mit dem Verhalten in Unity 4.6+ (dem frühesten, das ich getestet habe) überein, in dem aktuelle Eingaben bereits bei FixedUpdate verfügbar sind. Wenn Sie Eingaben verwenden, um physikalische Antworten zu generieren, kann durch die Verarbeitung in FixedUpdate tatsächlich ein Latenzzeitrahmen im Vergleich zu Update entfernt werden. Es ist nur besondere Sorgfalt erforderlich, um Doppelhandhabung oder Überspringen von Eingaben zu vermeiden. In jedem Fall ist das Überprüfen einer int-Variablen in FixedUpdate nicht die Ursache für den in der Frage beschriebenen
Stillstand
1
Aus tatsächlicher Erfahrung sprechen. Das Überprüfen auf Eingaben in FixedUpdate führt zu Latenzproblemen / fehlgeschlagenen Eingaben und unerwünschtem Verhalten. Meines Wissens (seit Unity 3.2 / 3.3) wurde FixedUpdate speziell für das Physiksystem entwickelt. Überprüfen Sie das Update auf Eingabe, nicht auf FixedUpdate. Meine Antwort steht. Möchten Sie Ihre Kommentare zu einer Antwort machen?
Robert French