Jump to content
Unity Insider Forum

isGrounded macht komisches


Sir_Mathew

Recommended Posts

Hi,

Ich hab ein ganz komisches Problem.

Und zwar fällt beim Run mein Chararakter auf den Boden, aber mit Luft dazwischen. Also er Schwebt. 

In einen anderen Projekt Funktioniert das aber so, wie ich es habe.

Dachte das es vielleicht am Model liegt. Also hab ich einfach eine Kugel und ein Block gemacht. Die Kugel dem Charaktercontroller hinzugefügt aber dennoch bleibt Luft Zwischen Block und der Kugel.

im Debug.Log wird auserdem angezeigt das is Grounded True mal False hat.

Die Kollisionshüllen sind genauso groß wie die Objekte.

Hier noch der Code, ich hoffe ihr könnt mir Helfen:

 public GameObject player;
   
    CharacterController ccPlayer;

    float flPlayerMausXInput = 0.0f;
    float flPlayerMausYInput = 0.0f;

    float flPlayerTastaturHorizontalInput = 0.0f;
    float flPlayerTastaturVerticalInput = 0.0f;
    bool blPlayerTastaturSpringenInput = false;

    float flPlayerBewegungHorizontal = 0.0f;
    float flPlayerBewegungSpeed = 2.0f;
    float flPlayerDrehungSpeed = 6.0f;

    int intSprungPower =1;
    int intGravity = 50;

    Vector3 vec3PlayerBewegung;

    // Start is called before the first frame update
    void Start()
    {
        ccPlayer = player.GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {

    }

    void FixedUpdate()
    {
        //////////Maus Input//////////
        flPlayerMausXInput = Input.GetAxis("Mouse X");
        flPlayerMausYInput = Input.GetAxis("Mouse Y");

        //////////Tastatur Input//////////
        flPlayerTastaturHorizontalInput = Input.GetAxis("Horizontal");
        flPlayerTastaturVerticalInput = Input.GetAxis("Vertical");
        blPlayerTastaturSpringenInput = Input.GetButton("Jump");


        ////////Player//////////
        flPlayerBewegungHorizontal -= flPlayerMausXInput * flPlayerDrehungSpeed;
        player.transform.localEulerAngles = Vector3.down * flPlayerBewegungHorizontal;
        vec3PlayerBewegung.x = flPlayerTastaturHorizontalInput;
             
        vec3PlayerBewegung.z = 0;
        vec3PlayerBewegung = transform.TransformDirection(vec3PlayerBewegung);
        ccPlayer.Move(vec3PlayerBewegung * Time.deltaTime * flPlayerBewegungSpeed);

        if ((blPlayerTastaturSpringenInput == true) && (ccPlayer.isGrounded == true))
        {
            vec3PlayerBewegung.y = intSprungPower;
        }

        if (ccPlayer.isGrounded == false)
        {
            vec3PlayerBewegung.y -= intGravity * Time.deltaTime;
        }
        else
        {
            if (blPlayerTastaturSpringenInput == false)
            {
                vec3PlayerBewegung.y = 0;
            }
        }

        Debug.Log(ccPlayer.isGrounded);


    }

 

isGrounded.jpg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Moin,

damit ein CharacterController als isGrounded gilt, muss er mit dem Boden kollidieren. Wenn du auf dem Boden stehst und deshalb die vertikale Bewegung auf 0 stellst, dann bewegt sich der CC parallel zum Boden, was keine Kollision bedeutet. Deshalb hast du da abwechselnd True und False in der Konsole stehen. Du bist grounded, bewegst dich parallel zum Boden. Dadurch bist du nicht mehr grounded, Gravitation beschleunigt nach unten, Kollision mit dem Boden, wieder grounded.

Ein bisschen Abstand lässt der CC zwischen sich und den Collidern, mit denen er kollidiert. Das ist auch erstaunlich wichtig. Dieser Abstand ist in der Einstellung "Skin Width" zu sehen. Wenn du deine Kugel also relativ zum CC um 0.08 nach unten bewegst, gleichst du diesen Abstand wieder aus.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Lass dein Character immer nach unten bewegen, egal ob er auf dem Boden steht oder nicht.

In Reallife ist es genau so. Wir haben ganze Zeit eine Erdanziehung, egal ob wir springen oder auf dem Boden stehen. Würden wir keine Anziehung haben, weil wir den Boden berühren, würden wir kurze zeit auch weg fliegen und wieder auf den Boden sein.. wie bei dir halt true und false, hehe.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi, danke euch beiden. 

Erstmal zu @MaZy deine Lösung hab ich gerade mit meinen Problem getestet und es bringt das gleiche wie vorher, also nix.

@Sascha Also wenn ich es richtig verstehe, nehme ich ein Leeres Gameobjekt, füge Spieler als Child hinzu und korrigiere meinen Spieler Abstand zum Boden.

Das habe ich mal getestet und da gemerkt das 0.08 Einheiten verschieben keineswegs reicht. Da mir dieser Schritt aber etwas komisch erschien, weil das wäre ja eigentlich das selbe, als wenn ich die Kollisionshülle beim Spieler verschiebe, hab ich ein neues Projekt gemacht und weiter gesucht.

Was mich wunderte war dann, das die Kollisionshülle für ein Leeres Gameobjekt echt riesig war.

Hab dann mein Altes Projekt nochmal genauer angeschaut. Da hab ich gemerkt, das ich meinen Spieler um 100 und mein Boden um 1000 hoch Skaliert habe.

Mein Aktuelles Projekt hat eine Skalierung von 0.1. Von dem Hintergrund aus betrachtet ist bei dem einen der Abstand 0.08 zum Boden bei dem einen Projekt eine riesige Lücke und im anderen eine kleine nicht sichtbare Lücke.

Hab nun alles auf 100 Skaliert, die Kamera weiter weg geschoben und den Bildausschnitt mit Size auf 500 eingestellt, damit die großen Figuren auch ins

Kamerabild passen. Nun sieht alles echt Super aus.

Danke euch allen für die Hilfe

 

Lösung.jpg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am 24.2.2022 um 17:44 schrieb Sir_Mathew:

Hi, danke euch beiden. 

Erstmal zu @MaZy deine Lösung hab ich gerade mit meinen Problem getestet und es bringt das gleiche wie vorher, also nix.

Komisch, ich habe das Projekt nochmal geöffnet, wo ich genau das Problem gelöst habe (dafür wurde ich sogar bezahlt). 
Grob tue ich das:
 

currentGravity += Physics.gravity.y * gravityMultiplier;

if (controller.isGrounded)
{
    currentGravity = Physics.gravity.y * gravityMultiplier;
    Debug.Log("true");

    if (Input.GetKeyDown(KeyCode.Space))
    {
        currentGravity += jumpForce * gravityMultiplier + -Physics.gravity.y * gravityMultiplier;
    }

}
else 
{
    Debug.Log("false");
}

Also wie in Reallife Charakter nach unten bewegen.. gibt es ein Widerstand wird nicht mehr addiert sondern die selbe Gravitation jedes Frame gesetzt..
Wird Space gedrückt, also in Reallife gegen die Gravitation Kraft ausgeführt, bewegt man sich halt nach oben.

(ich glaube man kann es auch so berechnen currentGravity += (jumpForce + -Physics.gravity.y) * gravityMultiplier;)

Unity_2022-02-27_15-53-11.png.04e2eff90e0fac865a1ea94c358e568e.png

Wie du siehst, hab ich nur true stehen.

Ich erkläre dir auch warum das so ist.
Konzept vom CC. Der CharacterController berührt den Boden.. jedoch ist der CharacterController in dem Frame wo Move() ausgeführt wurde aber im Boden und nicht auf dem Boden und wird daher nach oben verschoben. Sobald er diese Position erreicht hat, wo über den Boden ist, heißt es isGround = false. 
Allerdings gab da noch eine Sache. Ich glaube isGround zeigt den letzten Wert von der letzten Frame. Sprich, Wenn du Move() einsetzt wird dann isGround auch erst gesetzt. In deinem Fall sollte aber korrekt sein, da du nachdem Move() isGround überprüfst.

(Am Rande: Ich muss auch zugeben, dass dein Code echt schwer für mich ist zu lesen. Überall Prefix wie f, und vec3 gibt mir jedes mal kleine Verzögerung bzw. Denkpause um zu erkennen um welchen Variable es gerade geht.)

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor einer Stunde schrieb MaZy:

(Am Rande: Ich muss auch zugeben, dass dein Code echt schwer für mich ist zu lesen. Überall Prefix wie f, und vec3 gibt mir jedes mal kleine Verzögerung bzw. Denkpause um zu erkennen um welchen Variable es gerade geht.)

Ist doch ganz easy.

fl=float

int=int

vec3=vector3

bl=bool

usw.:D

woran erkennst du denn an deinen Variablen denn, um was es sich da handelt z-b- gravityMultiplier?

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo

Ungarische Notation ist, natürlich ist das eine sehr persönliche Meinung, absolut unnötig und dazu verwirrend, weil man spätestens bei eigenen Klassen an die Grenzen der Schreibweise kommt. Woran man erkennt, welchen Typ eine Variable hat? Am besten nimmst du einen aussagekräftigen Namen und zur Not hilft die IDE. Ich weiß nicht, wann ich das letzte mal über solch ein Problem gestolpert bin.  

Dazu machst du so etwas und das hilft wirklich keinem, oder?

CharacterController ccPlayer;

 

Ich finde es auch besser ohne!

 

Christoph

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 9 Stunden schrieb Sir_Mathew:

Ist doch ganz easy.

fl=float

int=int

vec3=vector3

bl=bool

usw.:D

woran erkennst du denn an deinen Variablen denn, um was es sich da handelt z-b- gravityMultiplier?

 

Es geht mir nicht um die Übersetzung und was für ein Type das ist, sondern jedes mal sehe ich die ersten Buchstaben, die überall auftauchen und erkenne nicht welche Variable das ist. Das führt bei mir zu Koordinationsprobleme. Ich sehe nicht sofort, wo dasselbe auftauchen könnte, sondern ich sehe erst mal alle gleich. Daher bin ich gezwungen viel mehr zu lesen als ich brauche. Bei gravity reicht ja schon, wenn gravity erkenne und weiß direkt, ok geht um gravity und sehe auch dieses Wort gravity und kann schneller identifizieren. Ob es nun gravityMultiplier ist oder gravityBounce was auch immer ist erst mal egal. 
Meistens schreibt auch Klassen, wo nicht so viel steht und daher ist das merken auch wesentlich einfacher.

Heutzutage brauchen wir das nicht, dass wir den Typen zu erkennen. Unser IDE also Editor zeigt doch bereits an, ob es um Player, float oder sonst was geht. Auch bei Namen. Wenn ich Player sehe weiß ich es ist Player. Steht da playerController oder playerCharacterController (wobei ich das nie Player nenne ehrlich gesagt), weiß ich geht um de Controller. Steht da gravityMultiplier weiß ich entweder float oder int, aber einmal angeschaut, weiß ich dass es float ist und das vergisst man nicht so schnell.

Das gleiche machen übrigens im Asset Folder auch. Muss zu geben, da finde ich nicht sooo schlimmer, weil dort auch eher um die Suche geht z.B. wenn man "p" schreibt direkt prefabs angezeigt werden sollen, aber da wir so oder so t:Prefab eingeben können und alle Prefabs angezeigt werden ist das auch unnötig. Wir haben im Asset ordner symbole, die definieren, ob wir ein prefab sehen, ein model sehen, oder texturen usw.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am 27.2.2022 um 16:07 schrieb MaZy:

Komisch, ich habe das Projekt nochmal geöffnet, wo ich genau das Problem gelöst habe (dafür wurde ich sogar bezahlt). 
Grob tue ich das:

Öhm nur weil man Bezahlt wird, ist es nicht besser oder sonstiges. Und ich sage nochmal, es lag nur an der Skalierung. Meine Skalierung betrug 0,1 also mein Player

ist nur ca. 2,5 Einheiten Groß, also kleine wie jede Maus. Da macht ein Abstand von 0,08 sehr viel aus, also knapp 30% einer Figur. Bei Höheren Skalierungen sieht man sowas nicht.

Hat also nix mit Code zu tun.

Am 27.2.2022 um 18:14 schrieb chrische5:

Ungarische Notation ist, natürlich ist das eine sehr persönliche Meinung, absolut unnötig und dazu verwirrend, weil man spätestens bei eigenen Klassen an die Grenzen der Schreibweise kommt. Woran man erkennt, welchen Typ eine Variable hat? Am besten nimmst du einen aussagekräftigen Namen und zur Not hilft die IDE. Ich weiß nicht, wann ich das letzte mal über solch ein Problem gestolpert bin.  

Naja ganz Ungarische Nation ist ja meinen nicht, aber ich sehe gern, wenn ich auf meine Variable sehe, was das ist.

Und das die IDE das anzeigt, nutzt ja auch nix wenn man es hier Postet. Aber ein eindeutigen Namen geben?

Also da sag ich nur Gravity. Woran erkenne ich an diesem Namen was das für eine Variable ist?

Es kann Integer, Float oder genauso gut auch ein Bool sein. Bevor jetzt alle sagen Bool geht nicht, doch es geht.

Spiel im Weltraum Gravity false, auf der erde Gravity true. 

Und für die Stärke wäre z.b. GravityPower als Integer oder Float.

Am 28.2.2022 um 03:12 schrieb MaZy:

Es geht mir nicht um die Übersetzung und was für ein Type das ist, sondern jedes mal sehe ich die ersten Buchstaben, die überall auftauchen und erkenne nicht welche Variable das ist

Also die Buchstaben verwirren dich? Woran erkennst du denn eine Variable, am Namen? 

Also welche Variable wäre deiner Meinung nach Murasch? Wie du selbst siehst, erkennst du daran Garnix.

Da fällt mir gleich meine alte Beschriftung von Variablen in Lite-C ein

Z.B.

int_global_freigabe_waffe_1

Ist doch vollkommen klar war das ist...

Globale Integer der Waffe 1 freischaltet :D

Ich hatte sogar noch längere Bezeichnungen, finde die aber nicht mehr....

So und nun, das Thema ist ja Gelöst, also Figuren haben einen Minimalen Abstand zueinander, die man bei sehr Kleinen Figuren sehen kann und bei großen nicht.

Hatte sowas irgendwie mal gelesen, das ein Abstand Notwendig ist, damit Figuren nicht im Boden etc. hängen bleiben oder so.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 weeks later...
Am 2.3.2022 um 18:10 schrieb Sir_Mathew:

Also die Buchstaben verwirren dich? Woran erkennst du denn eine Variable, am Namen? 

Also welche Variable wäre deiner Meinung nach Murasch? Wie du selbst siehst, erkennst du daran Garnix.

Da fällt mir gleich meine alte Beschriftung von Variablen in Lite-C ein

Z.B.

int_global_freigabe_waffe_1

Ist doch vollkommen klar war das ist...

Globale Integer der Waffe 1 freischaltet :D

Ich hatte sogar noch längere Bezeichnungen, finde die aber nicht mehr....

Nee keine Verwirrung. Sondern Koordinationsproblem. Woran ich was erkenne? Du meinst wahrscheinlich den Variabletypen?

@chrische5hat das schon als Beispiel gezeigt. So mach ich es auch. Auch wie er schon bereits sagt, kann man für sich persönlich machen wie man will, nur war es für mich hart zu lesen.

Ich erkenne etwas, weil es sehr gut übersetzt und leserlich geschrieben wurde.

IsGravityOn, IsGravityActive, IsGravityEnabled (Oder GravityIsActive bzw IsOn hört sich auch mal besser an)  führt alles zu true oder false. Kann man auch kürzen mit GravityActivated, GravityEnabled.

PlayerCount = Anzahl der Spieler (Int)
Players (oder GetPlayers()) = Ne liste mit Players (List<Int> oder []int usw)

Hierbei ist mir nicht wichtig, um zu wissen was für ein Typ das ist, wenn ich es lesen will und verstehen will. Sollte ich damit anfangen zu arbeiten, muss ich so oder so nur einmal wissen, was mich da erwartet. Also je nach Editor z.B. Rider wird es gleich angezeigt, oder in Visual Studio kann man mit Maus drüber bzw. auch kann man bei der Deklaration an anschauen. Das reicht bereits um damit für die nächste Zeit zu arbeiten.

Beispiel habe ich hier die Anzahl der Spieler = PlayerCount .

Es würde nicht NumberPlayerCount oder IntPlayerCount stehen oder iPlayerCount. Einfach nur PlayerCount, da es üblich ist, dass da ein Int dahinter steckt bzw auch logisch ist. Es wird bestimmt nicht 1,5 Spieler existieren :D.

Bei deinem Beispiel ohne int davor also global_freigabe_waffe_1 würde man das nicht so leicht erkennen, aber das liegt auch daran, das es nicht leserlich bzw, nicht herauslesbar.

GlobalReleasedWeaponIndex_1 z.B: sagt durch Index. Aber das ist immer noch falsch. Bei mir wäre es, wenn es hart darauf kommt.

Globals.ReleaseWeapon(int index) und ändert Werte dann von array oder so ähnlich.

 

Am 2.3.2022 um 18:10 schrieb Sir_Mathew:

Öhm nur weil man Bezahlt wird, ist es nicht besser oder sonstiges.

Das hab ich nirgends behauptet. Ich hab nur am Rande erwähnt, dass bei mir so ein Problem war und so gelöst habe und ich da in dem Moment für eine Spielefirma gearbeitet habe und sie als Lösung akzeptiert haben. Ich sagte ja nirgends, dass es besser sei oder ich besser bin. Hab halt nur noch erklärt, warum das Problem auftritt. Vorher hatte ich herum probiert. Und wenn ich danach google gibt es endliche Threads, wo viele das gleiche wie bei mir behaupten. Aber natürlich kann es bei dir in dem Fall ganz anderes Problem sein.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...