CircleCast穿过对撞机

时间:2016-11-23 13:50:52

标签: c# unity3d

我正在研究自定义物理行为并使用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 个答案:

答案 0 :(得分:1)

当铸造对象与起始位置处的对撞机重叠时,未注册命中是默认行为。要解决此问题,请检查项目设置物理2D管理器中的查询开始在碰撞器中框。

如果您不希望所有查询出现此行为,则可能需要查看光线投射,因为光线投射在对撞机中启动的可能性要小得多。如果您决定使用射线投射,请取消上面的框并开始射线 你的球员/球的对手本身。这样你就可以确定你永远不会错过任何命中,因为射线在违规对撞机内部开始。