Проблема с поворотами, при смене гравитации в Unity

Итак, у меня проблема в моей игре с поворотами игрока.

Код с управлением игрока (включая повороты):

using UnityEngine;
using UnityEngine.SceneManagement;

{

    using UnityEngine.SceneManagement;
    using UnityEngine;

    public class Movement : MonoBehaviour
   
    private Rigidbody2D rb;

    public float speed;
    public float moveInput;
    public float normalSpeed;

    public bool facingRight = true;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        speed = 0f;
    }

    private void FixedUpdate()
    {
        rb.velocity = new Vector2(speed, rb.velocity.y);
        if(facingRight == false && moveInput > 0)
        {
            Flip();
        }
        else if(facingRight == true && moveInput < 0)
        {
            Flip();
        }
    }

    public void OnLeftButtonDown()
    {
        if (speed >= 0f)
        {
            speed = -normalSpeed;
            transform.eulerAngles = new Vector3(0, 180, 0);
        }
    }

    public void OnRightButtonDown()
    {
        if (speed <= 0f)
        {
            speed = normalSpeed;
            transform.eulerAngles = new Vector3(0, 0, 0);
        }
    }

    public void OnButtonUp()
    {
        speed = 0f;
    }

    void Flip()
    {
        facingRight = !facingRight;
        Vector3 Scaler = transform.localScale;
        Scaler.x *= -1;
        transform.localScale = Scaler;
    }
}

и сам код с изменением гравитации :

{

    using UnityEngine;

    public class SvitchGravity : MonoBehaviour

    private Rigidbody2D rb;
    private Movement movement;

    private bool top;

    void Start()
    {
        movement = GetComponent<Movement>();
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            rb.gravityScale *= -1;
            Rotation();
        }
    }

    void Rotation()
    {
        if(top == false)
        {
            transform.eulerAngles = new Vector3(0, 180f, 180f);
        }
        else
        {
            transform.eulerAngles = Vector3.zero;
        }
        movement.facingRight = !movement.facingRight;
        top = !top;
    }
}

и когда я жму пробел, он становиться вот так :

как игрок становиться

А когда двигаю, вот так :

меняет свою ротацию

в общем, спасибо за ранее.

(Если есть вопросы, задайте в комментариях)


Ответы (1 шт):

Автор решения: Yaroslav

Нет, ты не junior, ты начинающий ?.

// что за жопа с форматированием?
using UnityEngine; 
// что в классе жвижения жедает SceneManagement?
// using не в класса, а перед

[RequireComponent(typeof(Rigidbody2D))] // делает тело обязательным компонентом
public class HorizontalMovement : MonoBehaviour
{
    // публичным должно быть только то что никак не сломает класс
    // если третий класс изменти facingRight на случайное значение или normalSpeed (ужасное название) то все будет сломано
    // public полей практически не должно существовать, это не безопасно

    [SerializeField] private float _speed = 3; // не должно быть публичным
    private Rigidbody2D _body;
    
    // задается скриптом контроля через Input.GetAxis или еще как или скриптом для врагов
    public float Vector { get; set; }
    public float CurrentSpeed => _body.velocity.x;

    // методы доступа всегда пишутся, у тебя все в разнабой, где написал, де нет, тяпляп шешбеш
    private void Start ()
    {
        _body = GetComponent<Rigidbody2D>();
    }
    
    private void FixedUpdate ()
    {
        // поскольку сам FixedUpdate имя не говорящее набор действий лучше именовать под методами
        UpdateMove();
        UpdateDiretion();
    }

    private void UpdateMove ()
    {
        float Vector = Mathf.Clamp(MoveVector, -1, 1);
        Vector2 velocity = _body.velocity;
        velocity.x = normalVector*_speed;
        _body.velocity = velocity;
    }

    private void UpdateDiretion ()
    {
        // -1/1 можно просто сравнить, никакие флаги для этого не нужны
        // Sign как можно понять по названию просто выдает знак числа в виде -1/1
        if (CurrentSpeed != 0 && Mathf.Sign(CurrentSpeed) != Mathf.Sign(transform.localScale.x))
        {
            Vector3 scaler = transform.localScale;
            scaler.x *= -1;
            transform.localScale = scaler;
        }
    }

    // все что связано с управлением должно быть в другом скрипте, сам класс Movement должен подходить и для врагов
    // OnLeftButtonDown, OnRightButtonDown и OnButtonUp тут не место
    // transform.eulerAngles зачем ты в них вертишь персонажа не понятно
}

// правильно что гравитация в другом классе поскольку это другая ответственность
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
// Svitch пишется через w!
public class GravitySwitcher : MonoBehaviour
{
    private Rigidbody2D _body;
    // что тут забыл Movement? просто по логике?

    // в чем функция флага top?
    bool IsSwitched => _body.gravityScale < 0;

    private void Start ()
    {
        _body = GetComponent<Rigidbody2D>();
    }

    // команду на свич должен давать класс управления, это иная ответственность, только функционал
    // это как рука и молоток, два разных объекта, молоток умеет только бить, но не делает это сам по себе, куда и с какой силой диктует рука
    public void Switch ()
    {
        _body.gravityScale *= -1;
        UpdateDiretion();
    }

    private void UpdateDiretion ()
    {
        Vector3 scaler = transform.localScale;
        scaler.y = Mathf.Sign(_body.gravityScale);
        transform.localScale = scaler;
    }

    // transform.eulerAngles зачем вертеть объект на 180? его же нужно отзеркаливать, а не вертеть...
}

public class PlayerControl : MonoBehaviour
{
    [SerializeField] private string _moveAxis = "Horizontal";
    [SerializeField] private KeyCode _gravityKey = KeyCode.Space;
    private HorizontalMovement _move;
    private GravitySwitcher _gravity;

    private void Start ()
    {
        _move = GetComponent<HorizontalMovement>();
        _gravity = GetComponent<GravitySwitcher>();
    }


    private void Update ()
    {
        if (_move != null)
            _move.Vector = Input.GetAxis(_moveAxis);
        if (_gravity != null && Input.GetKeyDown(_gravityKey))
            _gravity.Switch();
    }
}
→ Ссылка