2016-11-23 28 views
0

我正在研究自定義物理行爲並使用CircleCast來確定是否有地面/牆壁。但是在某些情況下,CircleCast會通過碰撞器而不碰它。似乎問題出現在起始圓圈稍微重疊一個對撞機時。CircleCast通過對撞機

我該如何解決它,或者我做錯了什麼?

using System.Collections.Generic; 
using UnityEngine; 

public class PlayerController : MonoBehaviour 
{ 
    public Rigidbody2D ball; 
    public CircleCollider2D circleCollider; 
    public float speed; 
    public LayerMask layerMask; 
    public bool grounded; 
    public Transform graphics; 
    public Transform startCast, endCast; 
    public GameObject tempBall; 

    private int maxPathSize = 5; 
    private Queue<GameObject> path; 
    private float realRadius; 
    private Vector2 roughDirection; 
    private float rayLength; 
    private Vector2 realDirection; 
    private Vector2 gravity; 
    private Vector2 preferedDirectionOfMove; 

    // Use this for initialization 
    void Start() 
    { 
     path = new Queue<GameObject>(); 
     realRadius = circleCollider.radius * ball.transform.localScale.x; 
     rayLength = realRadius + (realRadius/10); 
     gravity = new Vector2(0, -9.81f); 
    } 

    // Update is called once per frame 
    void Update() 
    { 
     // if (Time.frameCount % 10 == 0) 
     { 
      preferedDirectionOfMove = gravity; 
      if (Input.GetKey(KeyCode.RightArrow) && grounded) 
      { 
       preferedDirectionOfMove = ball.transform.right; 
      } 
      if (Input.GetKey(KeyCode.LeftArrow) && grounded) 
      { 
       preferedDirectionOfMove = -ball.transform.right; 
      } 

      Move(); 

     } 
    } 

    void Move() 
    { 
     if (grounded && preferedDirectionOfMove == gravity) 
      return; 
     Debug.Log("***********"); 
     AddToPath(ball.position); 
     realDirection = (preferedDirectionOfMove * speed * Time.deltaTime); 
     Color color = Color.black; 
     Vector2 oldPos = ball.position; 
     Color colorX = RandomColor(); 
     DrawX(ball.position, colorX, 0.2f, 1, 0.5f); 
     RaycastHit2D hit = Physics2D.CircleCast(ball.position, realRadius, realDirection.normalized, realDirection.magnitude, layerMask); 
     if (hit) 
     { 
      DrawX(hit.point, colorX, 0.2f, 0.5f, 1.5f); 
      SetAngle(hit); 
      ball.position = GetNewPosition(hit); 
      grounded = true; 
      Debug.Log("grounded: " + true); 
     } 
     else 
     { 
      ball.position += realDirection; 
      DrawX(ball.position, colorX, 0.2f, 0.5f, 1.5f); 
      Debug.Log("grounded: " + false); 
      color = Color.red; 
      grounded = false; 
     } 
     Debug.DrawLine(oldPos, ball.position, color, 1); 
    } 

    void AddToPath(Vector2 position) 
    { 
     GameObject go = Instantiate(tempBall, position, Quaternion.identity) as GameObject; 
     if (path.Count >= 5) 
     { 
      Destroy(path.Dequeue()); 
     } 
     path.Enqueue(go); 
    } 

    void DrawX(Vector2 position, Color color, float size, float duration, float shape) 
    { 
     Debug.DrawLine(position - Vector2.one * (size/2f), position + Vector2.one * (size/2f), color, duration); 
     Debug.DrawLine(position + new Vector2(-1 * shape, 1) * (size/2f), position + new Vector2(1, -1 * shape) * (size/2f), color, duration); 
    } 

    Color RandomColor() 
    { 
     return new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f), 1); 
    } 

    Vector2 GetNewPosition(RaycastHit2D hit) 
    { 
     return hit.point + ((Vector2)hit.normal * realRadius); 
    } 

    void SetAngle(RaycastHit2D hit) 
    { 
     float angle2 = AngleAtan2(hit.normal, Vector2.right); 
     ball.MoveRotation(angle2); 
    } 

    float AngleAtan2(Vector2 from, Vector2 to) 
    { 
     return Mathf.Rad2Deg * (Mathf.Atan2(to.y, to.x) - Mathf.Atan2(from.x, from.y)); 
    } 

    void OnCollisionEnter2D(Collision2D collision) 
    { 
     Debug.Log("collision enter"); 
    } 
} 

回答

1

當鑄造對象與開始位置的碰撞器重疊時未註冊命中是默認行爲。要解決此問題,請檢查查詢在碰撞開始物理2D管理器項目設置

如果您不希望所有查詢都出現這種情況,您可能需要查看光線投射,因爲光線投射在對撞機中啓動的機會要低得多。如果你決定採用光線投射,請取消上面的方塊,並開始的射線投射你的球員/球的對撞機本身。這樣,您就可以確定,因爲在違規對撞機內部開始射線,您將永遠不會錯過任何命中。

+0

上帝保佑你人 – user2686299