OnCollisionEnter2D вызывается только один раз

#c# #unity3d

#c# #unity3d

Вопрос:

У меня есть два объекта в моей сцене, один из которых имеет только BoxCollider2D (класс столбца), а второй объект имеет Rigibody2D , а также свой собственный BoxCollider2D (класс игрока).

Я добавил скрипт к первому объекту, у которого есть OnCollisionEnter2D . Я вижу, что он срабатывает, когда мой второй объект сталкивается с ним, и он возвращает мой 2-й объект обратно, когда он пытается войти.

Я вижу, что мой OnCollisionEnter2D метод вызывается. Но если я снова перемещу свой 2-й объект на свой первый объект, он снова вернется обратно, однако я не вижу, чтобы мой OnCollisionEnter2D метод вызывался во второй раз.

Это предполагаемое поведение? Если да, то какой метод будет вызываться каждый раз, когда происходит столкновение между этими двумя объектами?

Примечание: Я видел, OnCollisionStay2D как вызывался еще несколько раз, а затем он остановился. Я предполагаю, что это происходит, когда он выводит мой 2-й объект. Я также вижу, что OnCollisionExit2D никогда не вызывался. Я увеличил масштаб редактора и ясно увидел, что зеленые линии BoxCollider2D не перекрываются между моими объектами, поэтому он должен был выйти из столкновения, когда он отскакивает назад.

 public class Column : MonoBehaviour
{
    private BoxCollider2D columnColl;

    // Start is called before the first frame update
    void Start()
    {
        columnColl = GetComponent<BoxCollider2D>();
    }

    // Update is called once per frame
    void Update()
    {

    }

    private void OnCollisionExit2D(Collision2D collision)
    {
          Debug.Log("Collision Exit");
    }

    void OnCollisionStay2D(Collision2D collision)
    {
       //Debug.Log("Collision Stayed");
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        Debug.Log("Collision Happened");
    }
}    
  

и

 public class Player : MonoBehaviour
{
    public float xMoveSpeed = 1f;
    private Rigidbody2D rbody;

    // Start is called before the first frame update
    void Start()
    {
        rbody = GetComponent<Rigidbody2D>();    
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown("d"))
        {
            rbody.position = rbody.position   new Vector2(xMoveSpeed, 0);
        }
    }
}
  

Комментарии:

1. Не могли бы вы также показать нам свой код?

2. Я обновил исходный пост с кодом

Ответ №1:

Вы не должны «вручную» изменять rbody.position .

Скорее используйте Rigidbody.MovePosition

Используйте Rigidbody.MovePosition для перемещения жесткого тела в соответствии с настройкой интерполяции жесткого тела.

Если в Rigidbody включена интерполяция Rigidbody, вызов Rigidbody.MovePosition приводит к плавному переходу между двумя позициями в любых отображаемых промежуточных кадрах. Это следует использовать, если вы хотите непрерывно перемещать жесткое тело в каждом FixedUpdate .

Установите Rigidbody.position вместо этого, если вы хотите телепортировать жесткое тело из одной позиции в другую, без промежуточных позиций, которые отображаются.

Вы также должны скорее сделать это в FixedUpdate , который используется для физики вместо Update

 void FixedUpdate()
{
    if (Input.GetKeyDown("d"))
    {
        rbody.MovePosition(rbody.position   new Vector2(xMoveSpeed, 0);
    }
}
  

Также убедитесь, что хотя бы один из объектов не kinematic относится к OnCollisionEnter:

События столкновения отправляются только в том случае, если к одному из коллайдеров также прикреплено некинематическое жесткое тело.

Комментарии:

1. Спасибо за отзыв. Я изменил движение на MovePosition(), как и предлагалось, движение теперь кажется намного более плавным. Тем не менее, проблема по-прежнему сохраняется в том, что OnCollisionEnter2D() по-прежнему вызывается только один раз, а Exit никогда не вызывается, даже если строки столкновения полей не перекрываются. Мой объект Player не является кинематическим, в то время как столбец является. Может ли это быть проблемой со спрайтами? Я прикрепил файлы моего проекта для получения подробной информации: dropbox.com/s/38azi36lb5mph4o/TestProject.zip?dl=0