2D-Charakter-Controller in Einheit (versucht, Old-School-Plattformer zurückzubekommen)

11

In diesen Tagen versuche ich, einen 2D-Zeichencontroller mit Einheit zu erstellen (unter Verwendung von Phisics). Ich bin ziemlich neu in Physikmotoren und es ist wirklich schwer, das Kontrollgefühl zu bekommen, das ich suche. Ich würde mich sehr freuen, wenn jemand eine Lösung für ein Problem vorschlagen könnte, das ich finde:

Dies ist momentan mein FixedUpdate:

public void FixedUpdate()
{
    Vector3 v=new Vector3(0,-10000*Time.fixedDeltaTime,0);
    _body.AddForce(v);

    v.y=0;
    if(state(MovementState.Left))
    {
        v.x=-_walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=-_maxWalkSpeed;
    }
    else if(state(MovementState.Right))
    {
        v.x= _walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=_maxWalkSpeed;
    }

    _body.velocity=v;

    Debug.Log("Velocity: "+_body.velocity);
}

Ich versuche hier nur, den starren Körper unter Anwendung einer Schwerkraft und einer linearen Kraft für links und rechts zu bewegen. Ich habe ein physisches Material eingerichtet, das kein Prellen und 0 Reibung beim Bewegen und 1 Reibung bei Stillstand verursacht. Das Hauptproblem ist, dass ich Collider mit Steigungen habe und die Geschwindigkeit sich ändert, wenn ich aufsteige (langsamer), den Hang hinunterfahre (schneller) und auf einem geraden Collider gehe (normal). Wie könnte dies behoben werden? Wie Sie sehen, wende ich für die x-Achse immer die gleiche Geschwindigkeit an.

Für den Spieler habe ich es mit einer Kugel an der Fußposition eingerichtet, die der starre Körper ist, auf den ich Kräfte ausübe.

Jeder andere Tipp, der mir das Leben erleichtern könnte, ist willkommen :).

PD Als ich nach Hause kam, bemerkte ich, dass ich dieses Problem lösen konnte, indem ich eine konstante Kraft parallel zur Oberfläche des Spielers ausübte, aber ich weiß nicht, ob es die beste Methode ist.

Nicht schlecht
quelle
4
Old-School-Plattformer verwendeten handgestimmte "Cartoon-Physik" für die Sprungmechanik und die direkte Geschwindigkeitsregelung (dh überhaupt keine Physik) für die Gehbewegung. Wenn Sie den Charakter-Controller neu schreiben können, tun Sie dies, da es schwierig sein wird, eine matschige Physiksimulation in die knackigen Bewegungen der alten Schulspiele zu stecken.
Patrick Hughes
Das Problem beim Schreiben einer benutzerdefinierten Version besteht darin, dass die Kollisionserkennung verloren geht. Und es ist nicht einfach, es ohne Verwendung von Raycast neu zu erstellen (abhängig von der Umgebung usw. könnte es eine Menge davon sein). Wie gehen Sie mit diesen Situationen um?
Notbad
Sie können Collider für Dinge verwenden, die noch benutzerdefiniert animiert sind - wenn Sie kinematische Starrkörper verwenden. Ich würde garantieren, dass Sie in den meisten Situationen nicht wirklich Physik / Kräfte usw. für diese Art von Anwendung benötigen. Wenn Sie nach einem technischeren Blickwinkel suchen, suchen Sie vielleicht nach Human IK
Runonthespot
1
Def Grabenphysik in dieser Situation.
Ray_Garner

Antworten:

7

Wenn Sie nach Plattformspielern der alten Schule suchen, besteht der erste Schritt darin, die Physik ganz aufzugeben. Sie werden am Ende gegen das Physiksystem kämpfen, um die entschieden unrealistische Bewegung eines Plattformspielers der alten Schule zu erhalten. Schauen Sie sich diesen CharacterController- Ersatz an, der die Physik insgesamt in den Schatten stellt, um eine gute Vorstellung von einer Möglichkeit zu erhalten, ihn zu implementieren.

prime31
quelle
3

Sie wären wahrscheinlich glücklicher mit dem, was Mheona empfohlen hat. Aber wenn Sie die Physik von Unity verwenden möchten, möchten Sie sie wahrscheinlich verwenden ForceMode.VelocityChange.

Beispiel:

public void FixedUpdate()
{
    var v = Vector3.zero;
    if(state(MovementState.Left))
    {
        v.x=-_walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=-_maxWalkSpeed;
    }
    else if(state(MovementState.Right))
    {
        v.x= _walkSpeed*Time.fixedDeltaTime+v.x;
        if(Mathf.Abs(v.x)>_maxWalkSpeed) v.x=_maxWalkSpeed;
    }

    _body.AddForce(v, ForceMode.VelocityChange);

    Debug.Log("Velocity: "+_body.velocity);
}

Sie sollten auch die globale Schwerkraft in den Physikeinstellungen Ihres Projekts anwenden und für Objekte, die schneller fallen sollen, eine Komponente mit konstanter Kraft hinzufügen .

ForceMode.Impulseist ähnlich, wird aber von der Masse des Starrkörpers beeinflusst. Erschwert das Einstellen.

michael.bartnett
quelle
2

Auch wenn Sie die integrierte Character Controller-Komponente nicht mögen (wie ich), sehen Sie sich den Beispielcode der Unity für das 2D-Gameplay-Tutorial an .

Der Code implementiert ein vollständiges 2D-Gameplay mit sich bewegenden Plattformen, Feinden und Boxen mit Kollision unter Verwendung des Character Controllers.

Aber wenn Sie nicht einmal einen Blick darauf werfen möchten, empfehle ich Ihnen, den Einsatz von Physik zu minimieren und zu versuchen, ihr Verhalten mit Ihrem eigenen Code zu kopieren. Je nachdem, welche Art von 2D-Spiel Sie planen, funktioniert es möglicherweise ziemlich gut. Anstatt Kraft anzuwenden Rigidbody.velocity, um Ihren Charakter zu bewegen, könnten Sie sich direkt damit anlegen Transform.Translate(), wodurch das Objekt Transform.positionbasierend auf seiner Achse bewegt wird. Sie können das forwardund in backBezug auf das Objekt selbst oder möglicherweise die Plattform oder den Boden bestimmen Transform.up, sodass Sie wissen, ob es sich um eine Rampe handelt, und den Winkel kennen.

Auch wenn Sie eine Art Geschwindigkeitsregelungsatributte erstellen (z. B. wie lange die Taste gedrückt wird), können Sie diese zusammen mit Ihrer Richtung beim Übersetzen anwenden, um zu verhindern, dass Ihr Charakter ohne Geschwindigkeit etwas zu stark geneigt läuft, ähnlich wie bei Sonic the Hedgehog für Genesis / Mega Drive.

Wenn Sie sich dafür entscheiden, weiterhin Physik zu verwenden, kann ich Ihnen überhaupt nicht helfen, weil ich nicht so gut darin bin, aber seien Sie sich bewusst, dass es ein normales Verhalten ist, langsamer einen Hang hinaufzugehen, da der Körper mehr Kraft benötigt, um Schritt zu halten wie im wirklichen Leben.

Mheona
quelle
Das erste, was ich las, als ich zur Einheit kam, war dieses Tutorial. Das Problem ist, dass das Kontrollgefühl ziemlich schlecht ist. Deshalb wollte ich meine eigene Lösung finden. Wenn Sie jedoch mit der Verwendung von Transform.Translate () beginnen, ist es nicht so einfach, Steigungen und andere Dinge auszuführen. Sie müssen mehrmals strahlen (2 oder 3 für den Boden, mehr für die Richtung, in die Sie sich bewegen, abhängig von der Größe des Helden). Für mobile Geräte ist Raycast nicht gut und weniger, wenn Sie 5..n pro Kollisionserkennungsiteration ausführen müssen. Vielleicht könnte ich mich irren, aber ich denke nicht.
Notbad
1

Was Sie wollen, ist der eingebaute Character Controller . Durch Festlegen der step offsetEigenschaft für diese Komponente können Sie einen Spieler dazu bringen, sich mühelos auf und ab zu bewegen.

NoobsArePeople2
quelle
Es tut mir leid, dass ich nicht kommentiert habe. Ich wusste, dass es einen Character Controller in Unity gibt und dass ich ihn mehrmals verwendet habe, aber ich mag nicht, wie er sich verhält. Es ist eher für FPS geeignet, nicht für ein Plattformspiel, bei dem Bewegungsmechanik eines der wichtigsten Dinge ist.
Notbad
Ich denke, wenn Sie einmal mit den Einstellungen auf dem Character Controller herumgespielt haben, funktioniert es gut. Was hat Ihnen gefehlt?
NoobsArePeople2
Das erste, was ich nicht mag, ist, dass es im Vergleich zu üblichen starren Körpern mit etwas Strahlenwurf langsam ist. Da ich weiß, wie ich es erreichen kann, denke ich, dass ich einen leichteren Controller machen könnte. Ein weiteres Problem besteht darin, dass es sich um ein ungerades Verhalten von Kapseln / Kugeln an Plattformkanten handelt (es kann mit einigen weiteren Strahlengüssen gelöst werden). Deshalb möchte ich meine eigenen rollen.
Notbad
0

Geben Sie hier die Bildbeschreibung einIch nehme an, das liegt daran, dass die Kraft nicht parallel zur Plattform ist und das Ergebnis im Aufstieg niedriger und im Abstieg höher ist.

Wenn Sie eine relative Kraft auf das Koordinatensystem ausüben

AddRelativeForce

Sie möchten eine maximale Geschwindigkeit in "x" beibehalten und mit einem Skalar vergleichen. Denken Sie daran, dass die Geschwindigkeit ein Vektor ist, und setzen Sie vx und vy zusammen. In flachem Gelände ist vy Null, aber notwendigerweise an Hängen größer als Null.

Die Geschwindigkeit ändert sich entsprechend der Richtung des Körpers, und sein relativer vx ändert sich in Bezug auf seinen gesamten vx

Dies kann Ihr V auf eine Weise ändern, die Sie nicht möchten:

if (Mathf.Abs (v.x)> _ maxWalkSpeed) v.x = _maxWalkSpeed;

Das Beibehalten des gleichen globalen Vx mag dem Auge seltsam erscheinen. (Unerwünschte Beschleunigungen)

NorbyAriel
quelle