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

Рейтинг: 0Ответов: 0Опубликовано: 25.05.2023

В первом "мгновении": onGround = true;

Во втором "мгновении": 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 + "-Доп.прыжок");
    }
}

}

Ответы

Ответов пока нет.