2014-10-06 35 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位置。 – Imapler 2014-10-07 06:31:38

+1

并且如果'| speed | Spektre 2014-10-07 06:47:23

+0

你没有使用Unity内置的对撞机吗? – anothershrubery 2014-10-09 13:53:10

回答

2

我不使用统一,但我之前编码的物理模拟和发生这种情况通常是因为:

  1. 润+浮动轮错误

    是你正在衰减,所以如果你的对象是下降然后它再次弹起(高度h0)再次下降,然后再次弹起(高度h1<h0)...所以它振荡的幅度越来越低,但从未为零。

    如果你的使用过的引擎/框架有一些性能调整来加速碰撞测试或者不能以更高的精度处理碰撞测试,那么振荡就会错过边界碰撞,特别是只有平面边界而不是体积,或者如果命中接近边界的顶点。

    if (|speed|<some_minimal_safe_speed)然后将其设置为零,以停止跳动更好的将是left just surface tangent speed part而不是零

  2. 您可以通过消除低幅度振荡在我的评论这样提到避免这种错误的边界定义

    某些边界碰撞测试系统需要以特定方式定义边界对象,如:

    • 多边形绕组由轴
    • 顺序或由概率一些角度
    • 为了通过大小
    • 顺序的击中

    在文档,以便检查它与正确的,如果需要

  3. 采样率vs.模拟速度

    您在一定的时间间隔内对物体的位置,速度,状态进行采样。在碰撞检测时间内,物体通常在边界表面之下/之后,但通常不完全(取决于速度和时间间隔)。当speed*time_interval足够高时,物体被检测为碰撞,因此其速度在表面反射并被阻尼。

    但是由于在下一次迭代中衰减,位置仍然在边界之后,所以在迭代后它被作为正常边界命中并以错误方式反弹。这发生在更高的速度不低的...你可以阻止这种通过设置于表面砸点的位置(如@Imapler评论)和/或+以上一些表面