#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