Jump to content
Unity Insider Forum

Beschleunigung mit GetButton


Maxe

Recommended Posts

Ich möchte ein Fahrzeug beschleunigen, aber nicht mit "Vertical", sondern mit einem Button. 

So funktioniert es über "Vertical" gut:  Vector3 _forwardForce = transform.forward * _acceleration * Input.GetAxis("Vertical");

Mit Button funktioniert es nicht: Vector3 _forwardForce = transform.forward * _acceleration + Input.GetButton("Jump");

Da "Input.GetButton" ein Bool ist, habe ich es mit + versucht, aber VisualStudio erklärt mir, dass das mit Vector3 trotzdem nicht kompatibel ist. Wie ist es zu erreichen, dass eine stetig ansteigende Beschleunigung bis zu einer maximalen Geschwindigkeit erreicht wird und wenn ich den Button (hier: "Jump") loslasse die Geschwindigkeit nicht sofort auf 0 sinkt, sondern wie eine Motorbremse langsam verzögert.

Ich hatte gestern mehrere Stunden herumprobiert, leider habe ich meine fehlerhaften Codes jetzt nicht mehr, aber die will wahrscheinlich auch keiner sehen. :-) Jedenfalls habe ich mit "maxSpeed", "speed" usw. gearbeitet, das größte Problem war immer, dass die "speed" beim loslassen sofort auf 0 fiel.  

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moin!

Ich empfehle, das neue Input-System kennen zu lernen. Ist um einiges besser. Aber ansonsten solltest du mal im Input Manager vorbei schauen. Du nutzt hier die Default-Achsen und versuchst, sie im Code irgendwie gerade zu biegen. Im Input Manager kannst du aber die Achsen einfach gleich so einstellen, wie du sie brauchst. Statt "Jump" machst du eine Achse "Accelerate", so du Space zuweist. Mit weiteren Einstellungen, die du dir bei "Vertical" abschauen kannst, kannst du dieses Verhalten nachbauen, dass die Achse nicht sofort auf 0 fällt.

Allerdings ist dann die Frage, inwieweit sowas der Input Manager machen soll. Es ist schon nicht falsch, sowas im Code zu machen. Diese "Animation" zwischen 0 und 1 ist ja nur dafür da, um Tastatur und Gamepads ähnlicher zu machen. Wie deine Lösung am Ende aussehen soll, musst du selber entscheiden. Ich glaube, ich geb dir einfach mal ein paar Techniken.

  1. Ein bool in ein int oder float (0 oder 1) umwanden:
    meinBool ? 1 : 0
    // Beispiel
    float target = Input.GetButton("Accelerate") ? 1f : 0f;

     

  2. Einen Wert linear auf einen anderen Wert zulaufen lassen:
    // in Update oder FixedUpdate
    value = Mathf.MoveTowards(value, target, speed * Time.deltaTime)
      
    // Beispiel
    private float speed = 0f;
    public float maxSpeed = 20f;
    public float acceleration = 10f;
    
    private void Update()
    {
      float targetSpeed = Input.GetButton("Accelerate") ? maxSpeed : 0f;
      speed = Mathf.MoveTowards(speed, targetSpeed, acceleration * Time.deltaTime);
    }

     

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hmm, irgendwie komme ich nicht weiter. Programmieren scheint nicht mein Talent zu sein, fällt mir doch sehr schwer. Gibt es irgendwo einen Discord, wo man seine Fragen stellen kann? Ich will hier nicht zu sehr nerven.

Das neue Input System finde ich noch schwieriger, da man dazu kaum Tutorials findet und jeder eine andere Art hat die Scripts zu schreiben (was beim Programmieren wohl so üblich ist).  Ich hänge weiter an der "Bremsfunktion" fest. So sieht die Bewegung aus:

void Move()
    {
        if (Input.GetKey(KeyCode.W) || Input.GetButton("Fire1"))        //Beschleunigen
        {
            Vector3 forceToAdd = transform.forward;
            forceToAdd.y = 0;
            _rb.AddForce(forceToAdd * _speed * 10);
        }
        else if (Input.GetKey(KeyCode.S) || Input.GetButton("Fire3"))      //Rückwärts
        {
            Vector3 forceToAdd = -transform.forward;
            forceToAdd.y = 0;
            _rb.AddForce(forceToAdd * _speed * 10);
        }

        if (Input.GetKey(KeyCode.Space) &&  ??? >= 0)             //Bremse
        {
            Vector3 forceToAdd = transform.forward;
            forceToAdd.y = 0;
            _rb.AddForce(forceToAdd * _speed * _brakeForce);
        }

        

        Vector3 locVel = transform.InverseTransformDirection(_rb.velocity);
        locVel = new Vector3(0, locVel.y, locVel.z);
        _rb.velocity = new Vector3(transform.TransformDirection(locVel).x, _rb.velocity.y, transform.TransformDirection(locVel).z);
        
    }

Meine Idee war, Bei //Bremse (die drei ???) einzufügen, dass nur gebremst wird, wenn die RigidBody velocity größer null ist. Nur wie kann ich die aktuelle Beschleunigung bestimmen oder "abgreifen"?  Kann ich irgendwie das Ergebnis von  "_rb.AddForce" (_speed * 10f) als "derzeitigeGeschwindigkeit" definieren? So eine Funktion wäre sehr hilfreich. 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 1 Stunde schrieb Maxe:

Programmieren scheint nicht mein Talent zu sein, fällt mir doch sehr schwer.

Das hat nix mit Talent zu tun, am Anfang ist es immer schwer. Das ist normal, also nicht entmutigen lassen.

vor 1 Stunde schrieb Maxe:

Gibt es irgendwo einen Discord, wo man seine Fragen stellen kann? Ich will hier nicht zu sehr nerven.

Schau mal gründlich auf die Foren-Hauptseite ;) Aber keine Sorge, du darfst hier so viel fragen, wie du willst.

vor 1 Stunde schrieb Maxe:

[...] jeder eine andere Art hat die Scripts zu schreiben (was beim Programmieren wohl so üblich ist). 

Geht so. Klar gibt's ständig mehrere Wege zum Ziel, aber das InputSystem-Paket ist schon wirklich extrem.

vor 1 Stunde schrieb Maxe:

Meine Idee war, Bei //Bremse (die drei ???) einzufügen, dass nur gebremst wird, wenn die RigidBody velocity größer null ist. Nur wie kann ich die aktuelle Beschleunigung bestimmen oder "abgreifen"?  Kann ich irgendwie das Ergebnis von  "_rb.AddForce" (_speed * 10f) als "derzeitigeGeschwindigkeit" definieren? So eine Funktion wäre sehr hilfreich. 

Die Geschwindigkeit des Rigidbodys kriegst du über Rigidbody.velocity. Das ist ein Bewegungsvektor - also nicht einfach die Geschwindigkeit, sondern direkt die Richtung. Wenn du davon die Geschwindigkeit haben willst, musst du die Länge des Vektors anschauen:

_rb.velocity.magnitude

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke für deine Antwort, die magnitude hat geholfen.

Aber eine neue Frage stellt sich mir: 

Vector3 _forwardForce = transform.forward * _acceleration * Input.GetAxis("Vertical");     
_forwardForce = _forwardForce * Time.deltaTime * _rb.mass;                                 
_rb.AddForce(_forwardForce);       

Damit bewegt sich am Ende der _rb.  Das ganze ist ein "Fahrzeug", dass sich bei negativer Eingabe vorwärts bewegt, bei positiver Eingabe rückwärtige Kräfte einsetzen (also bremst).

Wie zu erwarten, geht der Übergang in den "Rückwärtsgang" fließend, sobald der _rb zum stehen gekommen ist und weiterhin eine positive Eingabe erfolgt. Wie könnte man verhindern, dass ab dem Stillstand weitere positive Eingaben einen Effekt haben (nur negative, für die erneute Fahrt vorwärts)?

Ich habe als Bool "_stehend" definiert:

  if(_rb.velocity.magnitude == 0)
        {
            _stehend = true;
        }

Aber das hat nicht funktioniert, wenn if (_stehend == true) {siehe ganz oben}  else if (_stehend == false) {return}.

Das hat natürlich nicht funktioniert, aus verschiedenen Gründen, schon weil sobald sich der _rb ein wenig bewegt sich nichts mehr abspielt. Ich wollte den Denkfehler trotzdem zugeben :-)

Wie könnte man das Problem lösen?

 

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du nutzt ja forward für die Beschleunigung. Das heißt, dass du in Richtung der Z Achse Kraft ausübst.
Das kannst du auch genau so abfragen. Eine Vorwärtsbewegung hat einen positiven Wert, Rückwärts wäre negativ.

Also frage einfach die Velocity des RB's ab. Und nutze am besten 2 boolsche Variablen. So etwa:

if( (Input.GetKey(KeyCode.W) || Input.GetButton("Fire1") ) && _rueckw == false){
  // ich habe keinen Rüeckwärtsgang drin, kann also jetzt los fahren und lege auch gleich den Vorwärstgang ein.
  _vorw = true;
  //...
}
if( (Input.GetKey(KeyCode.S) || Input.GetButton("Fire3") ) && _vorw == false){
  // ich habe keinen Vorwärtsgang drin, kann also rückwärts fahren und lege auch gleich den Rückwärstgang ein.
  _rueckw = true;
  //...
}

// hier wird jetzt ab einem gewissen Schwellenwert in der Nähe der 0 die entsprechende Variable zurück gesetzt.
if(_rb.velocity.z < 0.5f){ // sobald ich unter den Wert von 0.5 komme, fliegt der Vorwärtsgang raus (falls er denn drin war).
  _vorw = false;
}
if(_rb.velocity.z > -0.5f){ // sobald ich über den Wert von -0.5 komme, fliegt der Rückwärtsgang raus (falls er denn drin war).
  _rueckw= false;
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...