2014-10-06 5 views
1

Я в настоящее время реплицирую систему частиц в 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; 
     } 
    } 
} 

Любая помощь очень ценится.

+2

Когда столкновение происходит, попробуйте установить положение y на y pos плоскости. – Imapler

+1

, а также если '| speed | Spektre

+0

Вы не используете встроенные коллайдеры Unity? – anothershrubery

ответ

2

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

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

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

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

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

    if (|speed|<some_minimal_safe_speed) затем установить его в ноль, чтобы остановить подпрыгивая еще лучше было бы left just surface tangent speed part вместо нуля

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

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

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

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

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

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

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