Jump to content
Unity Insider Forum

Gravitationsverluste eliminieren


KosMos1989

Recommended Posts

Hallo zusammen,

ich habe ein kleines Problem mit Unity und hoffe das ihr mir helfen könnt.

Eine Kugel soll mit Addforce einmalig angestoßen werden und die Gravitation des Rigidbodys ist entsprechend eingeschaltet. Weiterhin wird bei bodenkontakt der Vektor reflektiert (klappt wunderbar)

Nun ist es so das die Kugel mit der Zeit an geschwindigkeit verliert und genau das ist nicht gewollt. Ich denke das sind Gravitationsverluste, kann man die irgendwie rausrechnen?

 

LG

KosMos1989

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moin!

Gravitationsverluste gibt's da keine. Du übst ja keine konstante Kraft nach oben aus. Wenn die Kollision mit dem Boden 100% Bounce hat und du keinen Drag an hast, dann sollte die Kugel abgesehen von mikroskopischen Rundungsfehlern immer wieder auf dieselbe Höhe kommen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Erstmal vielen Dank für die schnellen Antworten.

Aber ich glaube das Problem muss an der Gravitation liegen, denn ich habe diese speedverluste nur bei gravityscale = 1 und bei gravityscale = 0 wird die Kugel nicht langsamer. In der Realität ist es ja eigentlich auch genauso, da würde ein springender Ball auch an Geschwindigkeit verlieren.

Ich habe folgendes Codefragment programmiert:

(Falls wichtig, die Kugel hat einen CircleCollider und trifft auf einen geraden EdgeCollider)

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

public class JoulietController : MonoBehaviour
{

    private Rigidbody2D rb2d;
    public float speed;
    Vector2 richtung;
    Vector2 neueRichtung;
    Vector2 richtungKollision;

    void Awake()
    {
        this.richtung = Vector2.up;
        this.rb2d = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        rb2d.AddForce(this.richtung * speed * Time.deltaTime, ForceMode2D.Impulse);
        this.richtung = Vector2.zero;

        // Für Kollision
        this.richtungKollision = rb2d.velocity;
        
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        this.speed = richtungKollision.magnitude;
        this.neueRichtung = Vector2.Reflect(richtungKollision.normalized, collision.contacts[0].normal);
        rb2d.velocity = neueRichtung * this.speed;

    }
}

 

Hat da jemand eine Idee?

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Warum ist denn da jetzt konstante Beschleunigung drin? Jeden Frame auf's neue? Und dann noch als Impuls? Das ergibt nicht so viel Sinn? Im ersten Post hast du von einer springenden Kugfel geschrieben und nicht von einer konstanten Beschleunigung. Update ist sowieso nicht die richtige Stelle für AddForce, das gehört in FixedUpdate. Auch wenn's hier theoretisch debattierbar wäre. Und dann setzt du da per Hand die Geschwindigkeit auf einen Wert, der von irgendeinem andern Zeitpunkt kommt als von der Kollision (richtungKollision.magnitude)? Alles sehr verwirrend.

Wenn du ein Objekt haben willst, das 100% Bounce hat, also mit derselben Geschwindigkeit eine Kollision verlässt, mit der es aufgeprallt ist, dann gib dem Objekt ein Physic Material auf den Collider und stelle da Bounce auf 1. Stelle dann noch sicher, dass drag und angular drag auf 0 sind, um keinen Luftwiderstand pseudo-simuliert zu haben. Den ganzen Code brauchst du da nicht. Wenn du das trotzdem mal mit Code machen willst, dann müsste der auch anders aussehen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja ich habe das auch in FixedUpdate drin, aber update * deltaTime sollte aufs Gleiche hinaus laufen. Das ist auch nur ein Codegragment das mein Problem mit Unity beschreibt, der eigentliche Code hat wesentlich mehr Zeilen und die Richtung wird da z.b. durch einen Rechtsklick neu gesetzt.

Die Geschwindigkeit ist nicht konstant, da der richtungsVektor nach dem Anstoß auf Zero gesetzt wird. Es wird also konstant Zero multipliziert 😄

Es kann sein das ich das nicht sehr professionell programmiert habe, aber bei der Kollision habe ich eigentlich absolut keinen Geschwindigkeitsverlust, denn es klappt ja ohne aktive Gravitation (gravityScale = 0) einwandfrei.

Wie würde eine Lösung mit Psysic Material aussehen?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du machst ein neues in deinen Assets (Rechtsklick, Create, Physics Material 2D). Das selektierst du und stellst Bounciness auf 1. Dann ziehst du das Ding in die richtige Eigenschaft deines CircleCollider2Ds. Der Code kommt komplett runter, weil der sonst interferiert.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Vielen Vielen Dank Sascha

das war die Lösung für einige Probleme die ich hatte, aber ich habe wohl doch noch einen Geschwindigkeitsverlust beim Richtungswechsel.

Dieser ist wie folgt implementiert:

 

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

public class JoulietController : MonoBehaviour
{

    private Rigidbody2D rb2d;
    public float speed;
    Vector2 richtung;
    Vector2 richtungAenderung;
    Vector2 richtungKollision;

    void Awake()
    {
        this.rb2d = GetComponent<Rigidbody2D>();
        this.richtung = Vector2.up;
    }

    private void Update()
    {
        if (Input.GetMouseButtonUp(1))
        {
                // mausPosition speichern
                richtungAenderung = Camera.main.ScreenToWorldPoint(Input.mousePosition);

                // mausPosition korrecktur (muss beim Spieler beginnen, nicht bei x=0, y=0 / * 100 falls richtung < richtung.normalized
                richtungAenderung.x = 100 * (richtungAenderung.x - transform.position.x);
                richtungAenderung.y = 100 * (richtungAenderung.y - transform.position.y);

                rb2d.velocity = richtungAenderung.normalized * rb2d.velocity.magnitude;
        }
    }
   

    void FixedUpdate()
    {
        rb2d.AddForce(richtung * speed, ForceMode2D.Impulse);
        this.richtung = Vector2.zero;
    }

}

 

Hast du da auch noch einen Tipp für mich?

 

 

 

 

 

 

 

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe auch gerade mal in 2020.1.11 ein Physics Material benutzt und muss feststellen, dass der Ball bei einem Wert von 1 sogar jedes Mal ein bisschen höher springt. Das ist ziemlich sicher ein Bug...

Was aktuell das Problem ist, verstehe ich leider nicht so ganz. Die Grundidee stimmt schon, mit

neueGeschwindigkeit = neueRichtung.normalized * alteGeschwindigkeit.magnitude;

Die Zeilen davor sind etwas unnötig - das * 100 brauchst du nicht, und Komponenten rechnen musst du auch nicht selber. Statt

richtungAenderung.x = 100 * (richtungAenderung.x - transform.position.x);
richtungAenderung.y = 100 * (richtungAenderung.y - transform.position.y);

schreibst du also einfach

richtungAenderung = richtungAenderung - transform.position;

obwohl ich das nochmal anders benennen würde, weil deine Variable vor und nach dieser Zeile komplett unterschiedliche Dinge beschreibt.

Du brauchst auch keine Instanzvariable dafür, eine lokale Variable tut's völlig.

Also insgesamt:

var mausPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
var neueRichtung = (mausPosition - transform.position).normalized;
var alteGeschwindigkeit = rigidbody.velocity.magnitude;

rigidbody.velocity = neueRichtung * alteGeschwindigkeit;

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...