2016-05-02 9 views
0

ユニティで衝突が衝突するのを防ぐにはどうすればよいですか?私は2D物理を使用しており、矢印を木箱に貼り付けたい。コリジョンコールバックで剛体とコライダーを簡単に取り外すことはできますが、衝突力のフレームがまだ矢印に加えられているため、位置と回転がわずかにジャンプしているようです。コリジョンコールバックのリジッドボディの設定は、この1つのフレームが適用されるのを妨げないようです。コリジョンコールバックのユニティフィジックスにおける衝突力の防止

私はUnityに衝突の物理を適用しないようにしたいと考えています。

矢印の寿命に運動学を使用することは、矢印が何かに当たるまで現実に飛ぶ必要があるため、オプションではありません。ここで

は、衝突を扱うクレートオブジェクトのコードです:

protected virtual void HandleCollision(ArrowScript arrow, Collision2D coll) 
{ 
    StickArrow(arrow, coll); 

    if (DestroyAfterSeconds >= 0.0f) 
    { 
     Destroy(arrow.gameObject, DestroyAfterSeconds); 
    } 
} 

private void OnCollisionEnter2D(Collision2D coll) 
{ 
    ArrowScript script = coll.gameObject.GetComponent<ArrowScript>(); 
    if (script != null) 
    { 
     HandleCollision(script, coll); 
    } 
} 

private bool StickArrow(ArrowScript arrow, Collision2D coll) 
{ 
    Vector2 surfaceNormal = coll.contacts[0].normal; 
    float surfaceAngle = Mathf.Atan2(surfaceNormal.y, surfaceNormal.x); 
    float arrowAngle = Mathf.PI + (arrow.transform.eulerAngles.z * Mathf.Deg2Rad); 
    float angleDifference = Mathf.Abs(BowAndArrowUtilities.DifferenceBetweenAngles(surfaceAngle, arrowAngle)); 
    float penetration = arrow.PercentPenetration * PenetrationPercentageModifier * (1.0f - angleDifference); 
    if (penetration <= MinimumPenetrationPercentage) 
    { 
     arrow.PercentPenetration = 0.0f; 
     return false; 
    } 

    // Make the arrow a child of the thing it's stuck to 
    arrow.transform.parent = transform; 
    arrow.gameObject.transform.Translate(new Vector3(-penetration * arrow.Length, 0.0f, 0.0f)); 

    SpriteRenderer thisSpriteRenderer = GetComponent<SpriteRenderer>(); 
    if (thisSpriteRenderer != null) 
    { 
     arrow.GetComponent<SpriteRenderer>().sortingLayerID = thisSpriteRenderer.sortingLayerID; 
     arrow.GetComponent<SpriteRenderer>().sortingOrder = Mathf.Max(0, thisSpriteRenderer.sortingOrder - 1); 
    } 

    BowAndArrowUtilities.PlayRandomSound(arrow.CollisionAudioClips, penetration * 5.0f); 

    // destroy physics objects from the arrow (rigid bodies, colliders, etc.). This unfortunately doesn't prevent this frame from apply force (rotation, position) to the arrow. 
    arrow.DestroyPhysicsObjects(); 

    return true; 
} 

Unityのバージョンは5.3.4です。

+0

kinematicの使用を確認しましたか?私は外出することができますが、私はあなたが探しているものを達成するかもしれないと思います。ここをクリックしてください:http://docs.unity3d.com/Manual/class-Rigidbody.html – mtrueblood

+0

キネマティックを設定すると、矢印が空を飛ぶのを防ぐので、オプションではありません。コリジョンがジャンプフィーに影響を与えない場合、スクリプト内でキネマティックを設定する。 – jjxtra

+0

これはちょっとしたハックな解決策ではありません。あなたはいくつかのコードを提供できますか? – mtrueblood

答えて

0

私は矢印の頭をトリガーにした。 OnTriggerEnter2Dの中で、私は矢印が矢印のスプライトの幅を指している方向に円を描きます。トリガは、Unity物理計算の影響を受けません。

private void OnTriggerEnter2D(Collider2D coll) 
{ 
    ArrowScript script = coll.gameObject.GetComponent<ArrowScript>(); 
    if (script != null) 
    { 
     Vector2 dir = -script.ArrowHead.transform.right; 

     // ray cast with the arrow size y value (thickness of arrow) 
     RaycastHit2D[] hits = Physics2D.CircleCastAll(script.ArrowHead.transform.position, script.Size.y, dir); 
     foreach (RaycastHit2D hit in hits) 
     { 
      // collider2d is a member variable assigned in Start that is the Collider2D for this object 
      if (hit.collider == collider2d) 
      { 
       HandleCollision(script, hit.normal); 
       break; 
      } 
     } 
    } 
} 
+1

これはまさに私があなたに伝えようとしていたものですが、時間内に理解しました) GetComponentの呼び出しを避け、タグなどで識別してから、衝突を特定したらgetcomponentを試してください。常にパフォーマンスを念頭に置いてください。 – MalachiteBR

関連する問題