Jump to content
Unity Insider Forum

Character Flip


RexZ

Recommended Posts

Guten Abend zusammen,

ich bin noch recht neu bei Unity und C# und habe somit immer wieder Probleme. Das aktuelle bekomme ich aber einfach nicht gelöst.

Der Character dreht sich entsprechend zur Laufrichtung, wie er es auch soll. Wenn er jedoch nach links läuft und man "A" loslässt, dreht er sich automatisch nach rechts. Das habe ich eigentlich mit Flip() beheben wollen,  jedoch läuft der Character nun rückwärts, wenn er nach links läuft. Hier ein Video zur Veranschaulichung: https://www.youtube.com/watch?v=P1ndJWV_a4g

Hier mein aktueller Code:

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

public class Move2D : MonoBehaviour
{

    public float moveSpeed = 5f;
    public float jumpForce = 10f;
    public bool isGrounded = false;
    private Rigidbody2D rb;
    private float inputVertical;
    public float distance;
    public LayerMask whatIsLadder;
    private bool isClimbing;
    public Animator animator;
    private bool m_FacingRight = true;
    public float move;
    

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void FixedUpdate()
    {
        
    }

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

        float moveHorizontal = Input.GetAxis("Horizontal");
        
        animator.SetFloat("Horizontal", Input.GetAxis("Horizontal"));

        Jump();

        Vector3 movement = new Vector3(moveHorizontal, 0f, 0f);
        transform.position += movement * Time.deltaTime * moveSpeed;
        
        //Climbing stuff
        RaycastHit2D hitInfo = Physics2D.Raycast(transform.position, Vector2.up, distance, whatIsLadder);

        if (hitInfo.collider != null)
        {
            if (Input.GetKeyDown(KeyCode.W))
            {
                isClimbing = true;
            }
        }
        else
        {
            isClimbing = false;
        }

        if (isClimbing == true)
        {
            inputVertical = Input.GetAxis("Vertical");
            rb.velocity = new Vector2(rb.velocity.x, inputVertical * moveSpeed);
            rb.gravityScale = 0;
        }
        else
        {
            rb.gravityScale = 5;
        }

        // If the input is moving the player right and the player is facing left...
        if (moveHorizontal > 0 && !m_FacingRight)
        {
            // ... flip the player.
            Flip();
        }
        // Otherwise if the input is moving the player left and the player is facing right...
        else if (moveHorizontal < 0 && m_FacingRight)
        {
            // ... flip the player.
            Flip();
        }

    }

    void Jump()
    {
        if(Input.GetButtonDown("Jump") && isGrounded == true) {
            gameObject.GetComponent<Rigidbody2D>().AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
        }
    }

    void Flip()
    {
        // Switch the way the player is labelled as facing.
        m_FacingRight = !m_FacingRight;

        // Multiply the player's x local scale by -1.
        Vector3 theScale = transform.localScale;
        theScale.x *= -1;
        transform.localScale = theScale;
    }
}

Ich hoffe jemand kennt das Problem, bzw. erkennt was ich falsch gemacht habe 😅

Link zu diesem Kommentar
Auf anderen Seiten teilen

Gruß,

1. All die Bewegungssachen in FixedUpdate hauen (dann kann man schlechter mit CheatEngine die Geschwindigkeit manipulieren).

2. Das optische (Animation, Sprite etc..) in Update lassen, spart Performance.

Bewegen an sich tut er ja in die richtige Richtung nur der Sprite (die Figur) dreht sich nicht richtig.

Denke es liegt bei dir im Setup vom Animator, am besten mal den Animator komplett neu erstellen, dort kannst du auch booleans erstellen z.b flip,

 

Poste mal ein Bild von dem Animator Setup.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 3 Minuten schrieb MustafGames:

Gruß,

1. All die Bewegungssachen in FixedUpdate hauen (dann kann man schlechter mit CheatEngine die Geschwindigkeit manipulieren).

2. Das optische (Animation, Sprite etc..) in Update lassen, spart Performance.

Bewegen an sich tut er ja in die richtige Richtung nur der Sprite (die Figur) dreht sich nicht richtig.

Denke es liegt bei dir im Setup vom Animator, am besten mal den Animator komplett neu erstellen, dort kannst du auch booleans erstellen z.b flip,

 

Poste mal ein Bild von dem Animator Setup.

Vielen Dank für die schnelle Antwort und die Tipps.

image.png.fd0ccb99ac983b801b5bdc61b8b0b41a.png

So siehts momentan aus.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 1 Minute schrieb MustafGames:

Wenn du das ganze Flip Zeug mal weglässt indem du es mit /* Code */ ausklammerst.

Dein Setup könnte in etwa so sein:

wenn moveHorizontal

== 0 -> idle

kleiner 0 (z.b. -1) -> left

größer 0 (z.b. 1) -> right

Das klingt schon mal gut. Nur wie greife ich im Code zB auf RunRight aus dem Animator zu?

Link zu diesem Kommentar
Auf anderen Seiten teilen

image.thumb.png.1b7342bf503ed236faa8fa6fbc2a0155.png

Das habe ich schon so eingestellt. Mit dem auskommentierten Flip Code sieht es momentan so aus, dass er beim nach links laufen, wenn man "A" loslässt wieder nach rechts flippt:

https://www.youtube.com/watch?v=7WG-fCnMtbc

Und der "Preview source State" ist evtl. bisschen durcheinandern, weil ich da verschiedene Sachen ausprobiert habe, hat aber auch nichts gebracht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

float moveHorizontal = Input.GetAxis("Horizontal");
animator.SetFloat("Horizontal", Input.GetAxis("Horizontal"));

zu

animator.SetFloat("Horizontal", moveHorizontal);

und

float moveHorizontal = Input.GetAxis("Horizontal");

muss so Aussehen:

if (Input.GetAxisRaw("Horizontal") != 0) {
	moveHorizontal = Input.GetAxis("Horizontal");
}

dann bleibt der letzte Wert erhalten.

Alternativ wegen Idle kannst du auch

if (Input.GetAxis("Horizontal")) {

nehmen.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Du könntest auch das so machen:

Einen Boolean move, der nur aktiviert wird wenn Input.getAxis gedrückt wird, dann setzt du moveHorizontal

dafür nimmst du GetAxisRaw was ich oben geschrieben habe statt dem mit != 0

 

im Animator setzt du dann das so ein wenn move = true -> Bewegung in moveHorizontal Richtung

wenn false -> Idle + Richtung also brauchst du 2 Idle State (Idle Left, Idle Right).

wenn Input.getAxisRaw nicht gedrückt wird setzt du move zu false

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 2 Stunden schrieb RexZ:

 Habe ich das vom Code her so richtig verstanden? 

 

 

Mit dem Animator muss ich mal schauen, da kenne ich mich fast gar nicht aus.

image.png

Du kannst den Code hier im Forum auch  per klicken auf das Symbol: <> einfügen dann kann man den editieren.

if (Input...)  {

move = true;

moveHorizontal = Input.GetAxisRaw("Horizontal");

} else {

move = false;

}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 10 Stunden schrieb MustafGames:

1. All die Bewegungssachen in FixedUpdate hauen (dann kann man schlechter mit CheatEngine die Geschwindigkeit manipulieren).

2. Das optische (Animation, Sprite etc..) in Update lassen, spart Performance.

Sorry was? Das ist völliger Humbug. Also alles, bis auf Bewegungscode in FixedUpdate. Aber die Begründung ist Quatsch, sorry.

Link zu diesem Kommentar
Auf anderen Seiten teilen

1. für mich als Anticheater ist das schon wichtig, per CheatEngine kann man die Spielgeschwindigkeit verändern und das wirkt sich nur auf Update aus soweit ich das probiert habe.

2. Wenn ich den ganzen Code für die Optic in FixedUpdate mit reinstecke dann erhöht sich die Auslastung deutlich als wenn ich das in Update lasse.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also der Code sieht nun so aus:

void Update()
    {
        
        if (Input.GetAxis("Horizontal") != 0)
        {
            move = true;
            moveHorizontal = Input.GetAxisRaw("Horizontal");
        } else
        {
            move = false;
        }

        animator.SetFloat("Horizontal", moveHorizontal);
Zitat

im Animator setzt du dann das so ein wenn move = true -> Bewegung in moveHorizontal Richtung

wenn false -> Idle + Richtung also brauchst du 2 Idle State (Idle Left, Idle Right).

Da habe ich auch nach Recherche nichts gefunden, wie ich das anordne/umsetze. Ich habe im Animator ebenfalls einen bool namens "move" angelegt und habe eine Idle Left. (Idle Right ist ja schon der Default). Aber wie ich das nun anordne... keine Ahnung :(

image.thumb.png.58a63ece2dde5da598896ddf6f9f91a2.png

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 18 Stunden schrieb MustafGames:

1. für mich als Anticheater ist das schon wichtig, per CheatEngine kann man die Spielgeschwindigkeit verändern und das wirkt sich nur auf Update aus soweit ich das probiert habe.

2. Wenn ich den ganzen Code für die Optic in FixedUpdate mit reinstecke dann erhöht sich die Auslastung deutlich als wenn ich das in Update lasse.

Wie gesagt, ist einfach Quatsch. CheatEngine tut Dinge im Ram. Ram und Update/FixedUpdate hat exakt nichts miteinander zu tun. Und wenn du Performanceunterschiede siehst, wenn etwas von Update nach FixedUpdate kommt, dann liegt es nicht an FixedUpdate, sondern an deinem Fixed Timestep oder an deinem Code selbst.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

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

×
×
  • Neu erstellen...