OnTriggerEnter2D не вызывается последовательно

1

Гиф, который показывает несогласованности столкновений: http://imgur.com/QB4XOv0.gif

В моей игре Unity2D у меня есть рогатка (игрок), стреляющая шарами на стену (думаю, головоломка- головоломка типа Puzzle Bobble). Каждый из мраморов является клоном сборника, и каждый сборник имеет твердое тело с проверкой IsKinematic вместе с CircleCollider с проверенным OnTrigger.

Когда мрамор сталкивается с двумя боковыми стенками, я использую OnTriggerEnter2D() и поворачиваю угол так, чтобы он отскакивал от стен под углом. Когда мрамор сталкивается с верхней стенкой, он в основном замерзает, после чего я удаляю компонент жесткого тела и устанавливаю тег "topObjects".

Несоответствия возникают, когда мрамор сталкивается с другим мрамором. Иногда вызывается функция триггера, а другая - нет. Триггеры кажутся случайными и непредсказуемыми.

Вот мой код С# для обнаружения коллизий и поведения, которые идут вместе с ним (прикрепляется к мрамору):

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class RockMove : MonoBehaviour
{
    public float speed = 0.5f;
    private Vector2 direction = new Vector2(0, 1);

    // current angle
    private float currentAngleZ;
    // indendiary angle
    private float angleB;

    // rotation speed
    private float rot;

    // curving speed
    private float rotMod;

    // stops marble when collides with wall
    private bool IsMoving = true;


    void Start() {
    }

    void Update ()
    {

        if (IsMoving) {
            rot = RockSpawn.rot;

            currentAngleZ = transform.eulerAngles.z;

            rotMod = transform.position.x * -0.5f;
            // moves it forward + adds speed
            transform.Translate(direction * Time.deltaTime * speed, Space.Self);
            // curving
            transform.Rotate (0, 0, rotMod, Space.Self);
            if (transform.position.x >= 0) {
                // faster speed when near walls "gravity/magnetism"
                speed += transform.position.x * 8 * Time.deltaTime;
            }
            if (transform.position.x < 0) {
                // faster speed when near walls "gravity/magnetism"
                speed += transform.position.x * -8 * Time.deltaTime;
            }
        }
        else {
            // when object is stationary
            speed = 0;
        }
    }


    void OnTriggerEnter2D(Collider2D collider){

        // if collides with another marble

        if (collider.gameObject.tag == "topObjects" ) {
            // get rid of rigidbody
            // can't have 2 rigidbodies when 2 objects collide
            Destroy(rigidbody2D);
            // freeze movement
            IsMoving = false;

            Debug.Log ("you collided with a marble");

            // freeze rotation
            this.transform.Rotate (0, 0, 0, Space.Self);

            // assign the new tag
            this.tag = "topObjects";
        }
        else if(collider.name == "TopWall")
        {
            Destroy(rigidbody2D);
            IsMoving = false;

            Debug.Log ("you broke the fourth wall!");
            transform.Rotate (0, 0, 0);

            this.tag = "topObjects";
        }
        else {
            // bounce off walls
            currentAngleZ = transform.eulerAngles.z;
            angleB = 360 - (2 * currentAngleZ);
            transform.Rotate (0, 0, angleB);
        }
    }

}

Обновление. Простое изменение функции Update() на FixedUpdate(), похоже, сделало триггер более последовательным, однако все еще существуют несоответствия в том, как они обнаружены.

Я тестировал rigidbody2d.velocity, transform.position и различные другие функции преобразования, но Transform.Translate дал наилучшие результаты, отскакивая от стен, хотя это просто теоретически просто телепортирует объект в новое место.

Уменьшение скорости также не влияет на консистенцию вообще и не изменяет размер коллайдеров круга.

  • 0
    По моему опыту, события столкновения и триггера более последовательны при использовании основанного на физике движения, например, rigidbody.velocity .
  • 0
    Я думаю, что проблема связана с вашими стенами. Ваш gif показывает несогласованность столкновений только тогда, когда пузырь подпрыгивает на стене. Ваши стены настроены как триггеры или они просто обычные коллайдеры?
Показать ещё 2 комментария
Теги:
unity3d
unity3d-2dtools
physics

3 ответа

0

Здесь есть два очевидных момента:

1.) у вашего игрового объекта есть Rigidbody2D, поэтому вы не должны перемещать его через преобразование, а вместо этого через жесткое тело с такими функциями, как:

rigidbody2D.MovePosition()

а также

rigidbody2D.MoveRotation()

Просто посмотрите их в документации Unity.

2.) Положите все это на

void FixedUpdate()
{
    ...
}

Здесь все, что касается физического движка, также содержит много ресурсов в Интернете, чтобы прочитать об этом :)

  • 0
    Я попытался использовать Rigidbody2d.MovePosition () и MoveRotation (), однако ему удалось только немного подвинуть шарик вверх по экрану, а затем полностью остановиться. Я проверил, и в тот момент других коллайдеров не было, поэтому он остановился произвольно. Изменение OnTriggerEnter на OnTriggerStay также не устранило проблему, а также не переместило код преобразования в FixedUpdate ().
  • 0
    MovePosition работает в абсолютных позициях. это означает, что если вы хотите продвинуться вверх, вы должны использовать hardbody2D.MovePosition (hardbody2D.position + Vector2.up);
0

OnTriggerEnter2D должен работать последовательно независимо от того, используете ли вы физику или нет.

Однако, если gameObject остается в контакте с другим объектом gameObject, вы будете отмечать один раз OnTriggerEnter один раз, в самый первый момент, когда они сталкиваются. После этого вы можете получать информацию о том, все ли два объекта gameObject все еще сталкиваются, вызывая OnTriggerStay.

Затем, после того, как они перестанут сталкиваться, OnTriggerEnter перезагрузится и снова запустится при обращении к другому объекту gameObject, даже если это то же самое, что и раньше. Вы проверили это?

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

  • 0
    Спасибо за это, я попробую OnTriggerStay и сообщу, работает ли он.
  • 0
    Ну, не говоря о том, что вы должны обязательно использовать OnTriggerStay (), а просто о том, что это происходит так, просто чтобы сделать заметку на случай, если это может быть полезным.
-1

Я понимаю, что Kinematic RigidBodies не может столкнуться в 2D. Я все еще довольно новый, но я нашел это в нескольких ответах с моими собственными проблемами. Вы должны изучить его больше.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню