Привет, подскажите пожалуйста как делают "правильно" физику столкновений в этом движке. Столкнулся с несколькими проблемами:
Вот есть у меня герой с двумя коллайдерами. один (круглый) с трением 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
- Стенам сделать трение 2
Почему персонаж липнет к стене: потому что для движения прикладывается сила и когда персонаж упирается в стену, то его силой придавливает к ней и соответственно возникает трение.
На счет скатывание как лыжник: тут советую наклонять персонажа для эстетической красоты) А вообще если сделать как я предложил в самом начале, то такой эффект пропадет.
То что я предложил возможно не правильно, но мне кажется, что это должно решить данную проблему.
Смотрите также:
Комментарии
А что если пойти от обратного, т.е. у персонажа оставить только 1 коллайдер, а вот с землей и со стенами поэсперементировать:
- Земле сделать трение 1
- Стенам сделать трение 2
Почему персонаж липнет к стене: потому что для движения прикладывается сила и когда персонаж упирается в стену, то его силой придавливает к ней и соответственно возникает трение.
На счет скатывание как лыжник: тут советую наклонять персонажа для эстетической красоты) А вообще если сделать как я предложил в самом начале, то такой эффект пропадет.
То что я предложил возможно не правильно, но мне кажется, что это должно решить данную проблему.
То что я предложил возможно не правильно, но мне кажется, что это должно решить данную проблему.
Чуть опередил меня.
Обычно для состыковки земли и персонажа используется 1 коллайдер. В остальном лучше параметр трения у самих объектов подстроить.
А что если пойти от обратного, т.е. у персонажа оставить только 1 коллайдер, а вот с землей и со стенами поэсперементировать:
Земле сделать трение 1
Стенам сделать трение 2
спасибо, это помогло, только стенам 0 сделал, а ни 2) но за счет того что на земле есть трение, герою не получается разогнаться на той поверхности чтоб взлететь теперь).
На счет скатывание как лыжник: тут советую наклонять персонажа для эстетической красоты)
а как это в юнити сделать? если я задают FixedAngle false для ригидбоди, персонаж теряет ориентацию в окржающей среде и бегает то на спине то на лапах.
спасибо, это помогло, только стенам 0 сделал, а ни 2)
ой, опечатался) Я думал как-раз о том, чтобы 0 трение им сделать.
персонаж теряет ориентацию в окржающей среде и бегает то на спине то на лапах.
Вот оно что... Ну можно тогда попробовать делать это на основе скрипта. Брать нормаль соприкосновения с землей и поворачивать.
но за счет того что на земле есть трение, герою не получается разогнаться на той поверхности чтоб взлететь теперь).
А надо? Можно попробовать поиграться со значениями. А вообще это немного странно
На другом форуме подсказали еще решение:
По поводу съезжания когда стоишь на наклонной поверхности: попробуй отключать массу у Rigidbody2D компонента, если герой стоит на земле.
По поводу взлетания когда вбегает по наклонной: попробуй значительно увеличивать массу когда герой в воздухе.А вообще я советую отказаться от наклонных поверхностей вообще (ну или хотя бы крутых склонов). Такой тип контроллера с ними не ладит.
С этим вообще все красиво и аккуратно получается. дописал в скрипт Update
if (!grounded) { rb2d.mass = 100; } else { rb2d.mass = 0; }
и выставил значения параметров по другому
MoveForce = 0,01f;
JumpForce = 0,03f;
Hotspur, ну если честно то это очень странное и костыльное решение. И вообще массу ставить в 0 нельзя. У тебя возникнет проблема если ударить в персонажа чем-то (например ящий или камушек прилетел), то твоего персонажа сметет, когда он будет на земле, но если подпрыгнуть перед ударом, то все останется на месте => потенциальный баг
Hotspur, ну если честно то это очень странное и костыльное решение. И вообще массу ставить в 0 нельзя. У тебя возникнет проблема если ударить в персонажа чем-то (например ящий или камушек прилетел), то твоего персонажа сметет, когда он будет на земле, но если подпрыгнуть перед ударом, то все останется на месте => потенциальный баг
да я понимаю. сейчас у обеих решений плюсы и минусы. пытаюсь найти компромисс)
Возможность добавлять комментарии была ограничена
CollectableItemData.cs
[CreateMenuItem(fileName = "newItem", menuName = "Data/Items/Collectable", order = 51]