@Ebolik2

Как реализовать движение по диагональной лестнице 2d?

Есть вот такая импровизированная лестница:
641225d626341256667743.png
При передвижении по ней персонаж скатывается вниз, при этом, если прыгнуть на лестницу, то при падении на нее будет проигрываться анимация падения, хотя персонаж на земле и он может еще раз прыгнуть. Так же, при прыжке на лестнице персонаж подпрыгивает гораздо выше, чем обычно. Ну и последнее - при передвижении по лестнице персонаж персонаж, как бы сказать, видит ее как рампу и в самой верхней точке он просто вылетает, хотя по логике он должен прилипнуть к ней и чтобы двигался без всяких приколов...
Вот код, собирал с видосов
using UnityEngine;

public class PlayerController : MonoBehaviour
{
	public SpriteRenderer sr;
	public Animator animator;
	public Rigidbody2D rb;

    public float horizontalMove = 0f;
    public float runSpeed = 40f;
    
    [Range(0, .3f)][SerializeField] private float movementSmoothing = .05f;
    

    private Vector3 vector3 = Vector3.zero;
    bool crouch = false;

	// start is called before the first frame update
	void Start()
	{
		rb = GetComponent<Rigidbody2D>();
		sr = GetComponent<SpriteRenderer>();
		animator = GetComponent<Animator>();

        realSpeed = runSpeed;
	}

	// update is called once per frame
	void Update()
	{
        horizontalMove = Input.GetAxisRaw("Horizontal") * runSpeed;
        animator.SetFloat("Speed", Mathf.Abs(horizontalMove));

        Jump();
        CheckingGround();
        SitingCheck();

        if (rb.velocity.y < 0f && !onGround)
        {
            animator.SetBool("isFall", true);
        }
        if (rb.velocity.y == 0)
        {
            animator.SetBool("isFall", false);
        }
    }
    void FixedUpdate()
    {
        Move(horizontalMove * Time.fixedDeltaTime);

    }
    public float jumpForce = 700f;
	void Move(float move)
	{
        Vector3 targetVelocity = new Vector2(move * 10f, rb.velocity.y);

        rb.velocity = Vector3.SmoothDamp(rb.velocity, targetVelocity, ref vector3, movementSmoothing);



        if (move > 0 && !faceRight)
        {
            Flip();
        }
        else if (move < 0 && faceRight)
        {
            Flip();
        }
    }

    void Jump()
    {
        if (Input.GetKeyDown(KeyCode.Space) && onGround && !jumpLock)
        {
            rb.AddForce(new Vector2(0f, jumpForce));
        }
    }

    public bool faceRight = true;
    private void Flip()
    {
        faceRight = !faceRight;

        Vector3 theScale = transform.localScale;
        theScale.x *= -1;
        transform.localScale = theScale;
    }
    public bool onGround;
    public Transform GroundCheck;
    public float checkRad = 0.3f;
    public LayerMask Ground;

    void CheckingGround()
    {
        onGround = Physics2D.OverlapCircle(GroundCheck.position, checkRad, Ground);
        animator.SetBool("onGround", onGround);
    }

    public Transform TopCheck;
    private float TopCheckRadius = 0.3f;
    public LayerMask Roof;
    public Collider2D poseStand;
    public Collider2D poseSit;
    private bool jumpLock = false;

    public float realSpeed;
    public float crouchSpeed = 20f;
    void SitingCheck()
    {
        if (Input.GetKey(KeyCode.S))
        {
            animator.SetBool("isSit", true);
            poseStand.enabled = false;
            poseSit.enabled = true;
            jumpLock = true;
            runSpeed = crouchSpeed;
        }
        else if (!Physics2D.OverlapCircle(TopCheck.position, TopCheckRadius, Roof))
        {
            animator.SetBool("isSit", false);
            poseStand.enabled = true;
            poseSit.enabled = false;
            jumpLock = false;
            runSpeed = realSpeed;
        }
        

    }
}
  • Вопрос задан
  • 98 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Ezekiel4
Охотник на пиратов и сборщик монолитов
1) Почему нахождение на лестнице не вызывает остановку анимации падения?
Вангую на персонаже висит скругленный коллайдер - это от него. Прикол в том, что даже если вам кажется, что персонаж не движется, в Rigidbody2D со скруглённым коллайдером при условии, что вы стоите скруглённой частью на острие или другом круге, то постоянно возникает небольшое ускорение вниз, которое фейлит ваше условие:
if (rb.velocity.y < 0f && !onGround)
{
	animator.SetBool("isFall", true);
}

if (rb.velocity.y == 0) // вот это вот условие
{
	animator.SetBool("isFall", false);
}

По идее, должно хватить условия "onGround":
animator.SetBool("isFall", !onGround);

2) Почему прыжок с лестницы выше, чем с земли?
Высота разная, потому что вы применяете к персонажу именно силу, ведь она напрямую учитывается в пересчётах. Более того, высота может быть другой, если вы будете прыгать ещё от углов, стоя на месте или скользя вниз или вверх.
Есть много решений, вот два рандомных:
1. Обнулить вертикальную часть вектора velocity перед применением силы:
void Jump() {
	if (Input.GetKeyDown(KeyCode.Space) && onGround && !jumpLock) {
		rb.velocity = new Vector2(rb.velocity.x, 0);
		rb.AddForce(new Vector2(0f, jumpForce));
	}
}

2. Вообще заменить силу на мгновенное изменение скорости:
void Jump() {
	if (Input.GetKeyDown(KeyCode.Space) && onGround && !jumpLock) {
		rb.velocity = new Vector2(rb.velocity.x, jumpForce);
	}
}


3) Почему персонаж скатывается с угла?
Потому что стоит скругленной частью на угле. Замените коллайдер. Можете взять квадрат и слегка скруглить края, чтобы при горизонтальном движении не ударялся о стыки текстур (если такая проблема у вас вдруг вообще возникнет).
Типа такого
641258084edd0441102905.png
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы