Привет, подскажите пожалуйста как делают "правильно" физику столкновений в этом движке. Столкнулся с несколькими проблемами:
Вот есть у меня герой с двумя коллайдерами. один (круглый) с трением 1 для ног, второй (прямоугольный) с трением 0 чтоб не лип к стенам, когда прыгаешь в их сторону.
смотреть сюда
Так вот из-за того что у прямоугольного коллайдера стоит трение 0, то когда герой вбегает по наклонной поверхности (у поверхности трение 1, использовал материал как у ног героя) к стене, то он взлетает вверх и выглядит это ужасно :(
смотреть сюда
Была идея, что проблема с моим movementController'ом, потому что он позволяет двигаться в прыжке и из-за того герой липнет к стенам если трение 1 у прямоугольного коллайдера, но ведь почти во всех аналогичных играх можно двигаться в прыжке.
И еще одна проблема, что когда герой встает на наклонную поверхность, то съезжает с нее как лыжник, что тоже выглядит неправильно для таких игр (если поверхность не из льда).
смотреть сюда
MovementController.cs
смотреть сюда
public class MovementController : MonoBehaviour {

    [HideInInspector]
    public bool FacingRight = true;
    [HideInInspector]
    public bool Jump = false;
    public float MoveForce = 365f;
    public float MaxSpeed = 5f;
    public float JumpForce = 1000f;
    public Transform GroundCheck;

    private bool grounded = false;
    private Animator anim;
    private Rigidbody2D rb2d;

    void Awake()
    {
        anim = GetComponent<Animator>();
        rb2d = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        grounded = Physics2D.Linecast(transform.position, GroundCheck.position, 1 << LayerMask.NameToLayer("Ground"));
        if (Input.GetButtonDown("Jump") && grounded)
        {
            Jump = true;
        }
    }

    void FixedUpdate()
    {
        float h = Input.GetAxis("Horizontal");
        anim.SetFloat("Speed", Mathf.Abs(h));
        if (h * rb2d.velocity.x < MaxSpeed)
        {
            rb2d.AddForce(Vector2.right * h * MoveForce);
        }
        if (Mathf.Abs(rb2d.velocity.x) > MaxSpeed)
        {
            rb2d.velocity = new Vector2(Mathf.Sign(rb2d.velocity.x) * MaxSpeed, rb2d.velocity.y);
        }
        if (h > 0 && !FacingRight)
        {
            Flip();
        }
        else if (h < 0 && FacingRight)
        {
            Flip();
        }
        if (Jump)
        {
            anim.SetTrigger("Jump");
            rb2d.AddForce(new Vector2(0f, JumpForce));
            Jump = false;
        }
    }

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

Принятый ответ

А что если пойти от обратного, т.е. у персонажа оставить только 1 коллайдер, а вот с землей и со стенами поэсперементировать:
  1. Земле сделать трение 1
  2. Стенам сделать трение 2
Почему персонаж липнет к стене: потому что для движения прикладывается сила и когда персонаж упирается в стену, то его силой придавливает к ней и соответственно возникает трение.
На счет скатывание как лыжник: тут советую наклонять персонажа для эстетической красоты) А вообще если сделать как я предложил в самом начале, то такой эффект пропадет.
То что я предложил возможно не правильно, но мне кажется, что это должно решить данную проблему.
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
29
8 лет назад
0
А что если пойти от обратного, т.е. у персонажа оставить только 1 коллайдер, а вот с землей и со стенами поэсперементировать:
  1. Земле сделать трение 1
  2. Стенам сделать трение 2
Почему персонаж липнет к стене: потому что для движения прикладывается сила и когда персонаж упирается в стену, то его силой придавливает к ней и соответственно возникает трение.
На счет скатывание как лыжник: тут советую наклонять персонажа для эстетической красоты) А вообще если сделать как я предложил в самом начале, то такой эффект пропадет.
То что я предложил возможно не правильно, но мне кажется, что это должно решить данную проблему.
Принятый ответ
0
28
8 лет назад
Отредактирован Jusper
0
То что я предложил возможно не правильно, но мне кажется, что это должно решить данную проблему.
Чуть опередил меня.
Обычно для состыковки земли и персонажа используется 1 коллайдер. В остальном лучше параметр трения у самих объектов подстроить.
0
4
8 лет назад
0
А что если пойти от обратного, т.е. у персонажа оставить только 1 коллайдер, а вот с землей и со стенами поэсперементировать:
Земле сделать трение 1
Стенам сделать трение 2
спасибо, это помогло, только стенам 0 сделал, а ни 2) но за счет того что на земле есть трение, герою не получается разогнаться на той поверхности чтоб взлететь теперь).
На счет скатывание как лыжник: тут советую наклонять персонажа для эстетической красоты)
а как это в юнити сделать? если я задают FixedAngle false для ригидбоди, персонаж теряет ориентацию в окржающей среде и бегает то на спине то на лапах.
0
28
8 лет назад
0
а как это в юнити сделать? если я задают FixedAngle false для ригидбоди, персонаж теряет ориентацию в окржающей среде и бегает то на спине то на лапах.
Не очень понял, что alexprey имел ввиду. Но, легкое покачивание персонажа достигается подгонкой овального коллайдера.
0
29
8 лет назад
0
спасибо, это помогло, только стенам 0 сделал, а ни 2)
ой, опечатался) Я думал как-раз о том, чтобы 0 трение им сделать.
персонаж теряет ориентацию в окржающей среде и бегает то на спине то на лапах.
Вот оно что... Ну можно тогда попробовать делать это на основе скрипта. Брать нормаль соприкосновения с землей и поворачивать.
но за счет того что на земле есть трение, герою не получается разогнаться на той поверхности чтоб взлететь теперь).
А надо? Можно попробовать поиграться со значениями. А вообще это немного странно
0
4
8 лет назад
Отредактирован alexprey
0
На другом форуме подсказали еще решение:
По поводу съезжания когда стоишь на наклонной поверхности: попробуй отключать массу у Rigidbody2D компонента, если герой стоит на земле.
По поводу взлетания когда вбегает по наклонной: попробуй значительно увеличивать массу когда герой в воздухе.
А вообще я советую отказаться от наклонных поверхностей вообще (ну или хотя бы крутых склонов). Такой тип контроллера с ними не ладит.
С этим вообще все красиво и аккуратно получается. дописал в скрипт Update
        if (!grounded)
        {
            rb2d.mass = 100;
        }
        else
        {
            rb2d.mass = 0;
        }
и выставил значения параметров по другому
MoveForce = 0,01f;
JumpForce = 0,03f;
0
29
8 лет назад
0
Hotspur, ну если честно то это очень странное и костыльное решение. И вообще массу ставить в 0 нельзя. У тебя возникнет проблема если ударить в персонажа чем-то (например ящий или камушек прилетел), то твоего персонажа сметет, когда он будет на земле, но если подпрыгнуть перед ударом, то все останется на месте => потенциальный баг
0
4
8 лет назад
0
Hotspur, ну если честно то это очень странное и костыльное решение. И вообще массу ставить в 0 нельзя. У тебя возникнет проблема если ударить в персонажа чем-то (например ящий или камушек прилетел), то твоего персонажа сметет, когда он будет на земле, но если подпрыгнуть перед ударом, то все останется на месте => потенциальный баг
да я понимаю. сейчас у обеих решений плюсы и минусы. пытаюсь найти компромисс)
0
29
8 лет назад
0
Hotspur, не забудь потом рассказать что в итоге решил и отметить ответ)
Чтобы оставить комментарий, пожалуйста, войдите на сайт.