コード例 #1
0
    public List <Vector3> FindCirclePoint(List <Vector3> points, DynamicLight light)
    {
        for (int i = 0; i < points.Count; i++)
        {
            Vector2 direction = points[i] - light.transform.position;

            float distance = Mathf.Sqrt(direction.x * direction.x + direction.y * direction.y);

            RaycastHit2D[] hits = Physics2D.RaycastAll(light.transform.position, direction, distance, light.layer);

            bool touchAnotherCollider = false;
            foreach (RaycastHit2D h in hits)
            {
                if (h.collider != circle)
                {
                    touchAnotherCollider = true;
                    break;
                }
            }
            if (!touchAnotherCollider)
            {
                float angle = Light_Tools.GetAngle(direction);
                points[i] = new Vector3(points[i].x, points[i].y, angle);
            }
            else
            {
                points.Remove(points[i]);
                i--;
            }
        }
        return(points);
    }
コード例 #2
0
ファイル: Light_Box.cs プロジェクト: ShortyBatou/UnityTools
    //trouve tous les points qui sont "visibles" par la lumière
    public List <Vector3> FindPoint(List <Vector3> points, DynamicLight light)
    {
        for (int i = 0; i < points.Count; i++)
        {
            Vector2 direction = points[i] - light.transform.position;

            float distance = Mathf.Sqrt(direction.x * direction.x + direction.y * direction.y) - 0.05f;;
            if (distance <= light.GetRadius())
            {
                // on s'arrête juste avant le collider pour voir s'il touche quand même. Si c'est le cas alors le raycast se rentre dedans.
                RaycastHit2D hit = Physics2D.Raycast(light.transform.position, direction, distance - 0.05f, light.layer);

                // si le raycast ne touche rien alors le collider est en contacte direct avec la lumière
                if (!hit)
                {
                    float angle = Light_Tools.GetAngle(direction);
                    points[i] = new Vector3(points[i].x, points[i].y, angle);
                }
                // si le dernier point n'est pas le collider cela veut dire que,
                // normalement il aurait due être pris en compte mais un objet bloque la lumière
                else
                {
                    points.Remove(points[i]);
                    i--;
                }
            }
            else
            {
                points.Remove(points[i]);
                i--;
            }
        }
        return(points);
    }
コード例 #3
0
    public List <Vector3> GetVertices(List <Vector3> points, DynamicLight light)
    {
        // ---
        bool inversion = false;

        // on cherche la tangentes à du cercle passant par l'origine de la lumiére

        // le cercle du colider
        float x0 = center.x - light.transform.position.x;
        float y0 = center.y - light.transform.position.y;
        float r0 = circle.radius * circle.transform.localScale.x;

        // le cercle qui à pour point l'origine de la lumière, le centre du cercle collider, et les points des tangentes
        float x1 = x0 / 2;
        float y1 = y0 / 2;
        float r1 = Mathf.Sqrt(x1 * x1 + y1 * y1);

        if (Mathf.Abs(y0 - y1) < 0.3f)
        {
            inversion = true;
            float _ = x0;
            x0 = y0;
            y0 = _;

            _  = x1;
            x1 = y1;
            y1 = _;
        }

        float A, B, C, N, a, delta;

        // un coef utile pour ne pas répéter le calcul
        a = (x0 - x1) / (y0 - y1);

        // pareil
        N = (r1 * r1 - r0 * r0 - x1 * x1 + x0 * x0 - y1 * y1 + y0 * y0) / (2 * (y0 - y1));

        // on a une équation du second degrés du type Ax² + Bx + C =0
        A = a * a + 1;
        B = 2 * y0 * a - 2 * N * a - 2 * x0;
        C = x0 * x0 + y0 * y0 + N * N - r0 * r0 - 2 * y0 * N;

        // on trouve le delta
        delta = Mathf.Sqrt(B * B - 4 * A * C);

        // on en déduit les deux solutions
        for (int i = -1; i < 2; i += 2)
        {
            float x = (-B - delta * i) / (2 * A);
            float y = N - x * a;
            if (inversion)
            {
                float _ = y;
                y = x;
                x = _;
            }
            points.Add(new Vector3(x + light.transform.position.x, y + light.transform.position.y));
        }
        for (int i = 0; i < 2; i++)
        {
            Vector3 direction = points[i] - light.transform.position;
            points[i] = new Vector3(points[i].x, points[i].y, Light_Tools.GetAngle(direction));
        }
        return(points);
    }
コード例 #4
0
    // fait les tests pour les projections pour les ombres (  cercle ) //
    public List <Vector3> CreateCircleLimit(List <Vector3> points, DynamicLight light)
    {
        for (int i = 0; i < points.Count; i++)
        {
            Vector3 limite    = Vector3.zero;
            Vector3 direction = points[i] - light.transform.position;
            float   distance  = Mathf.Sqrt(direction.x * direction.x + direction.y * direction.y);
            if (light.GetRadius() - distance > 0)
            {
                RaycastHit2D[] hit   = Physics2D.RaycastAll(points[i], direction, light.GetRadius() - distance, light.layer);
                float          angle = direction.z;
                foreach (RaycastHit2D h in hit)
                {
                    if (h.collider != circle)
                    {
                        limite = h.point;
                        break;
                    }
                }
                if (limite == Vector3.zero)
                {
                    limite = new Vector3(light.transform.position.x + Mathf.Cos(angle) * light.GetRadius()
                                         , light.transform.position.y + Mathf.Sin(angle) * light.GetRadius()
                                         );
                }
                limite.z = angle;

                // redondance
                if (i < points.Count - 1)
                {
                    points.Insert(i, limite);
                    i++;
                }
                else if (points.Count == 1)
                {
                    float angleCollider = Light_Tools.GetAngle(circle.transform.position - light.transform.position);
                    if (points[0].z <angleCollider || points[0].z - angleCollider> Mathf.PI)
                    {
                        points.Insert(0, limite);
                    }
                    else
                    {
                        points.Add(limite);
                    }
                }
                else
                {
                    points.Add(limite);
                    i++;
                }
            }
        }
        if (Mathf.PI < Mathf.Abs(points[points.Count - 1].z) - Mathf.Abs(points[0].z))
        {
            Vector3 _ = points[0];
            points[0] = points[1];
            points[1] = _;

            _ = points[points.Count - 1];
            points[points.Count - 1] = points[points.Count - 2];
            points[points.Count - 2] = _;
        }
        return(points);
    }
コード例 #5
0
ファイル: Light_Box.cs プロジェクト: ShortyBatou/UnityTools
    public List <Vector3> CreateBoxLimit(List <Vector3> points, Collider2D collider, DynamicLight light)
    {
        int nbPoint = points.Count;

        for (int i = 0; i < nbPoint; i++)
        {
            float angle = Mathf.Abs(points[i].z);
            // le facteur permet de positionner un peu plus loin l'origine du point pour éviter que le raycast commence à la limite du collider
            Vector3 facteur = new Vector3(0.1f * Mathf.Cos(angle), 0.1f * Mathf.Sin(angle));

            Vector2 origine = points[i] + facteur;

            // la distance entre le centre de la lumière et le point d'origine de notre raycast c'est pour éviter que le raycast ne dépasse la limite du cercle
            if (!Physics2D.OverlapPoint(origine, light.layer))
            {
                Vector3 limite = new Vector3();

                Vector3 direction = points[i] - light.transform.position;

                float distance = Mathf.Sqrt(direction.x * direction.x + direction.y * direction.y);

                RaycastHit2D hit = Physics2D.Raycast(origine, direction, light.GetRadius() - distance, light.layer);

                if (hit)
                {
                    limite = hit.point;
                }
                else
                {
                    limite = new Vector3(light.transform.position.x + Mathf.Cos(angle) * light.GetRadius()
                                         , light.transform.position.y + Mathf.Sin(angle) * light.GetRadius()
                                         );
                }

                limite += new Vector3(0, 0, direction.z);
                float angleCollider = Light_Tools.GetAngle(collider.transform.position - light.transform.position);

                if (limite.z < angleCollider)
                {
                    if (Mathf.Abs(limite.z - angleCollider) > Mathf.PI)
                    {
                        points.Add(limite);
                    }
                    else
                    {
                        points.Insert(i, limite);
                        i++;
                        nbPoint++;
                    }
                }
                else if (limite.z > angleCollider)
                {
                    if (Mathf.Abs(limite.z - angleCollider) > Mathf.PI)
                    {
                        points.Insert(i, limite);
                        i++;
                        nbPoint++;
                    }
                    else
                    {
                        points.Add(limite);
                    }
                }
            }
        }

        if (Mathf.PI < Mathf.Abs(points[points.Count - 1].z) - Mathf.Abs(points[0].z))
        {
            Vector3 _ = points[0];
            points[0] = points[1];
            points[1] = _;
            _         = points[points.Count - 1];
            points[points.Count - 1] = points[points.Count - 2];
            points[points.Count - 2] = _;
        }
        return(points);
    }