Задать вопрос
@Dcat_me
обесняйте по-проще пойжалуйста.

Что делать если персонаж отрывается от кривой поверхности при резком изменении направления движения(при больших задержках)?

В первом "мгновении":
646d4956e5ff9512089572.png
onGround = true;
Во втором "мгновении":
646d49732d58c994617766.png
onGround = false;
Вот код:
{
{
    //States
    public bool Right = true;

    public bool onGround;
    public bool onUp;
    public bool Wall;

    public Vector2 Normal;
    public float Angle;

    public bool NormalUp;
    public bool NormalDown;

    //Walk
    public float Speed = 7;
    public Vector2 movement;

    //Jump
    public float JumpForce = 60;
    public float JumpControlTime = 0.3f;

    private bool JumpControl;
    private float JumpTime = 0f;
    //SecondJump
    public float DoubleJumpForce = 15;
    public int JumpCount = 2;

    private int MomentJumpCount = 0;

    //BugFix
    public bool canSlide = false;
    public PhysicsMaterial2D NoSlide;
    public PhysicsMaterial2D Slide;

    public bool CanEditVectorY = true;

    //functions
    private Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        //Application.targetFrameRate = 10;
    }

    void FixedUpdate()
    {
        States();
        BugFix();
        Jump();

    }

    void Update()
    {
        Walk();
        BugFixFPS();
        SecondJump();
    }

    public void OnTriggerStay2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Ground")
        {
            onGround = true;
        }
    }
    public void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.gameObject.tag == "Ground")
        {
            onGround = false;
        }
    }
    void States()
    {
        Vector2 downnormal = GetSurfaceAngle();// Используйте Physics2D.Raycast для получения нормали поверхности
        float downangle = Vector2.Angle(downnormal, Vector2.up);
        Normal = downnormal;
        Angle = downangle;

        if (Normal.x > 0)
        {
            NormalDown = true;
        }
        else
        {
            NormalDown = false;

            if (Normal.x < 0)
            {
                NormalUp = true;
            }
            else
            {
                NormalUp = false;
            }
        }
        //Debug.Log(Normal);
    }
    void BugFixFPS()
    {
	//Тут я питаюсь пофиксить подлёты
        if (rb.velocity.y > 0 && movement.x == 0 && onGround && Angle > 0 && CanEditVectorY)
        {
            rb.velocity = new Vector2(rb.velocity.x, -rb.velocity.y);
            Debug.Log("Именить вектор Y");
        }
    }

    void BugFix()
    {
	//Тут я делаю чтобы персонаж не скользил на кривых поверхностях когда стоит
        if (movement.x == 0 && !canSlide && Angle > 0)
        {
            rb.sharedMaterial = NoSlide;
        }
        else
        {
            rb.sharedMaterial = Slide;
        }
    }

    void Walk()
    {
        movement.x = Input.GetAxis("Horizontal");
        rb.velocity = new Vector2(movement.x * Speed, rb.velocity.y);

        if (movement.x < 0 && Right == true)
        {
            Flip();
            Debug.Log("в лево");
        }
        else if (movement.x > 0 && Right == false)
        {
            Flip();
            Debug.Log("в право");
        }
    }
    void Flip()
    {
        Vector3 scale = transform.localScale;
        scale.x *= -1;
        transform.localScale = scale;
        Right = !Right;
    }

    Vector2 GetSurfaceAngle()
    {
        RaycastHit2D hit = Physics2D.Raycast(transform.position, Vector2.down, Mathf.Infinity, LayerMask.GetMask("Ground"));

        if (hit.collider != null)
        {
            // Луч пересек коллайдер
            Vector2 normal = hit.normal; // Нормаль поверхности в точке пересечения
            //Debug.Log("Луч пересек коллайдер: " + hit.collider.name);
        }
        return hit.normal;
    }

    void Jump()
    {
        if (Input.GetKey(KeyCode.Space))
        {
            if (onGround && !onUp && !JumpControl)
            {
		//Тут я обнуляю вектор чтобы прыжки были всегда одинаковыми
                rb.velocity = new Vector2(rb.velocity.x, 0);
                Debug.Log("Обновление вектора => Прыжок");

                JumpControl = true;
            }
        }
        else
        {
            JumpControl = false;
        }
        if (JumpControl)
        {
	    //этот прыжок я буду менять
            if ((JumpTime += Time.fixedDeltaTime) < JumpControlTime)
            {
                rb.AddForce(Vector2.up * JumpForce / (JumpTime * 10));
            }
        }
        else
        {
            JumpTime = 0;
        }

        if (onGround)
        {
            MomentJumpCount = 0;
        }
    }
    void SecondJump()
    {

        if (Input.GetKeyDown(KeyCode.Space) && !onGround && !JumpControl && (++MomentJumpCount < JumpCount))
        {
            rb.velocity = new Vector2(0, DoubleJumpForce);
            Debug.Log(MomentJumpCount + "-Доп.прыжок");
        }
    }
}
  • Вопрос задан
  • 72 просмотра
Подписаться 1 Сложный Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Dcat_me Автор вопроса
обесняйте по-проще пойжалуйста.
Я придумал вот это:
{
        if (rb.velocity.y > 0 && movement.x == 0 && onGround && Angle > 0 && CanEditVectorY)
        {
            rb.velocity = new Vector2(rb.velocity.x, -rb.velocity.y);
            Debug.Log("Именить вектор Y");
        }
}

Но если я попытаюсь подкинуть персонажа он сразу стопится.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы