Почему реакция столкновения позволяет прыгающей сфере в конечном итоге проходить через плоскость?

1

В настоящее время я реплицирую систему частиц в Unity (С#). Я добавляю физику к каждой частице (представленной сферой), чтобы она могла отскакивать от плоскости, расположенной в начале координат. Частица отскакивает несколько раз, будучи затронутой гравитацией. По мере того, как отскоки становятся меньше, сфера начинает проходить через плоскость, пока, наконец, не провалится. Сила тяжести будет непрерывно воздействовать на частицу. Каков правильный способ остановить сферу на вершине самолета?

До сих пор я включил свою реализацию, но код всегда в конечном итоге позволяет сфере падать через плоскость.

ОБНАРУЖЕНИЕ:

public bool SpherePlaneCollisionDetection(Particle part)
{
            Vector3 sphereCenter = part.position;
            Vector3 planeCenter = Vector3.zero;
            Vector3 normal = Vector3.up;
            double radius = 0.5;

            Vector3 dist1 = (sphereCenter - planeCenter);
            float finalDist = Vector3.Dot (dist1, normal);

            if (finalDist > radius) {
                    return false;
            } else {
            //Debug.Log ("COLLISION HAS OCCURED");
            //Debug.Log ("POSITION: " + part.position);
            //Debug.Log ("FINAL DIST: " + finalDist);
                    return true;
            }
    }

ОТВЕТ:

public void HandlePlaneCollision()
{
    for (int i=0; i<Particles.Count; i++) {
        //Particle p1temp = Particle[i];
        Particle tempParticle = (Particle)Particles[i];
        //Particle part = tempParticle.GetComponent<Particle>();


        float dampning = 0.8f;
        float bounce = -1f;
        if(SpherePlaneCollisionDetection(tempParticle))
        {
            tempParticle.velocity.y *= (bounce*dampning);
            tempParticle.velocity.x *= friction;
            tempParticle.velocity.z *= friction;

            Debug.Log(tempParticle.velocity.y);

            Particles[i] = tempParticle;
        }
    }
}

Любая помощь приветствуется.

  • 2
    Когда произойдет столкновение, попробуйте установить положение y в положение y плоскости.
  • 1
    а также, если |speed|<some_minimal_speed затем установить его на ноль, чтобы остановить подпрыгивание (лучше было бы оставить только часть скорости касательной поверхности вместо нуля, смотрите здесь: stackoverflow.com/a/26223410/2521214 )
Показать ещё 2 комментария
Теги:
unity3d
collision
particle-system
physics

1 ответ

2
Лучший ответ

Я не использую Unity, но раньше кодировал физическое моделирование, и это обычно происходит потому, что:

  1. демпфирование + плавающие ошибки

    да, вы увлажняете, поэтому, если ваш объект падает, он снова отскакивает (высота h0) снова падает, а затем снова отскакивает (высота h1<h0)... поэтому он колеблется с более низкой и меньшей амплитудой, но никогда не равен нулю.

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

    Вы можете избежать этого , исключив колебания с более низкими амплитудами, как указано в моем комментарии, так:

    if (|speed|<some_minimal_safe_speed) то установите его на ноль, чтобы остановить прыжок еще лучше, останется только часть касательной скорости поверхности вместо нуля

  2. неправильное определение границы

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

    • полигональная обмотка
    • порядок по оси или некоторый угол
    • порядок по размеру
    • порядок по вероятности попадания

    поэтому проверьте его в документации и при необходимости исправьте

  3. частота дискретизации по сравнению с имитируемыми скоростями

    вы выбираете позицию объекта, скорость, состояние... через определенные промежутки времени. В момент обнаружения столкновения ваш объект обычно уже ниже/после граничной поверхности, но обычно не полностью (зависит от скорости и временного интервала). Когда speed*time_interval достаточно высока, объект обнаруживается как столкнутый, поэтому его скорость зеркально отражается на поверхности и затухает.

    Но из-за увлажнения в следующей итерации позиция все еще находится за границей, поэтому на итерации после того, как она обрабатывается как нормальный крайнюю попадание и отскок в неправильном направлении. Это происходит на более высоких скоростях, но не ниже... Вы можете предотвратить это , установив положение на точку попадания поверхности (как прокомментировал @Imapler) и/или + некоторую дельту над поверхностью

Ещё вопросы

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