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

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

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

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

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;
        }
    }
}

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


person Marcus Koz    schedule 06.10.2014    source источник
comment
Когда произойдет столкновение, попробуйте установить положение y на положение y плоскости.   -  person Imapler    schedule 07.10.2014
comment
а также, если |speed|<some_minimal_speed, то установите его на ноль, чтобы остановить подпрыгивание (лучше было бы оставить только часть касательной скорости поверхности вместо нуля, посмотрите здесь: stackoverflow. com/a/26223410/2521214)   -  person Spektre    schedule 07.10.2014
comment
Вы не используете встроенные коллайдеры Unity?   -  person anothershrubery    schedule 09.10.2014
comment
Я решил реализовать обнаружение/реагирование на столкновения без использования коллайдеров.   -  person Marcus Koz    schedule 13.10.2014


Ответы (1)


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

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

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

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

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

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

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

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

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

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

  3. частота дискретизации и моделируемая скорость

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

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

person Spektre    schedule 09.10.2014