예제 #1
0
    private static Vector2[] GetCorners(Collider2D c)
    {
        if (c is BoxCollider2D box)
        {
            Vector2 size = box.size * 0.5f;
            return(new Vector2[4] {
                box.transform.TransformPoint(new Vector3(size.x, size.y)),
                box.transform.TransformPoint(new Vector3(-size.x, size.y)),
                box.transform.TransformPoint(new Vector3(size.x, -size.y)),
                box.transform.TransformPoint(new Vector3(-size.x, -size.y))
            });
        }
        if (c is CircleCollider2D circle)
        {
            float radius  = circle.radius;
            var   results = new List <Vector2>();
            for (int i = 0; i < 360; i += 10)
            {
                results.Add(circle.transform.TransformPoint(Vector2Utils.FromAngle(i) * radius));
                //Debug.DrawLine(Vector3.zero, Vector2Utils.FromAngle(i) * radius, Color.white, 20f);
            }
            return(results.ToArray());
        }

        return(new Vector2[0]);
    }
예제 #2
0
    public static List <Vector2> GetPointsInArc(float fovAngle, float fovDistance, float offsetAngle, Vector2 origin, int resolution)
    {
        var   results    = new List <Vector2>();
        float startAngle = offsetAngle + fovAngle * 0.5f;

        for (int i = 0; i <= resolution; i++)
        {
            float angle = startAngle - i * (fovAngle / resolution);
            results.Add(Vector2Utils.FromAngle(angle) * fovDistance + origin);
        }

        return(results);
    }
예제 #3
0
    public static List <Vector2> GetFilteredPoints(float fovAngle, float fovDistance, float offsetAngle, Vector2 origin)
    {
        var   results     = new List <Vector2>();
        var   forward     = Vector2Utils.FromAngle(offsetAngle);
        float distanceSqr = fovDistance * fovDistance;
        float halfAngle   = fovAngle * 0.5f;

        foreach (var p in ObstacleManager.Corners)
        {
            Vector2 direction = (p - origin);
            if (Vector2.Angle(direction, forward) < halfAngle && direction.sqrMagnitude < distanceSqr)
            {
                results.Add(p);
            }
        }

        return(results);
    }
예제 #4
0
    /// <summary>
    /// Gets global points of FOV
    /// </summary>
    /// <param name="fovAngle">angle of field of view (degrees)</param>
    /// <param name="fovDistance">distance of field of view</param>
    /// <param name="resolution">Resolution in rays per degree</param>
    /// <param name="offsetAngle">rotation of object in degress (0 means facing right, 90 means up)</param>
    /// <param name="origin">origin of field of view</param>
    /// <returns>list of global points</returns>
    public static List <Vector3> GetPointsFromFOV(float fovAngle, float fovDistance, float resolution, float offsetAngle, Vector2 origin, LayerMask mask)
    {
        var results   = new List <Vector3>();
        var arcPoints = GetPointsInArc(fovAngle, fovDistance, offsetAngle, origin, Mathf.RoundToInt(fovAngle * resolution));
        var corners   = GetFilteredPoints(fovAngle, fovDistance, offsetAngle, origin);
        var forward   = Vector2Utils.FromAngle(offsetAngle);

        bool[] arcHits = new bool[arcPoints.Count];

        // Getting all points along the arc
        for (int i = 0; i < arcPoints.Count; i++)
        {
            Vector2 p = arcPoints[i];
            results.Add(Raycast(origin, (p - origin).normalized, fovDistance, mask, out bool hitted));
            arcHits[i] = hitted;
        }

        // Getting all points for corners
        foreach (var c in corners)
        {
            Vector2 dir = (c - origin).normalized;
            AddByAngle(origin, forward, results, Raycast(origin, Quaternion.Euler(0, 0, 0.05f) * dir, fovDistance, mask, out bool hitted));
            AddByAngle(origin, forward, results, Raycast(origin, dir, fovDistance, mask, out hitted));
            AddByAngle(origin, forward, results, Raycast(origin, Quaternion.Euler(0, 0, -0.05f) * dir, fovDistance, mask, out hitted));
        }

        for (int i = 0; i < arcHits.Length - 1; i++)
        {
            if (arcHits[i] != arcHits[i + 1])
            {
                Vector2 edgePoint;
                bool    hit;
                if (!arcHits[i] && arcHits[i + 1])
                {
                    // Edge to right of arc Point i
                    edgePoint = Raycast(arcPoints[i], arcPoints[i + 1] - arcPoints[i], Vector2.Distance(arcPoints[i], arcPoints[i + 1]), mask, out hit);
                }
                else
                {
                    // Edge to left of arc Point i + 1
                    edgePoint = Raycast(arcPoints[i + 1], arcPoints[i] - arcPoints[i + 1], Vector2.Distance(arcPoints[i], arcPoints[i + 1]), mask, out hit);
                }

                if (!hit)
                {
                    continue;
                }

                Vector2 hitPoint = Raycast(origin, edgePoint - origin, Vector2.Distance(origin, edgePoint), mask, out hit);
                if (hit)
                {
                    AddByAngle(origin, forward, results, hitPoint);
                }
                else
                {
                    AddByAngle(origin, forward, results, edgePoint);
                }
            }
        }

        return(results);
    }