Esempio n. 1
0
    public void Unfog(Vector3 position, float radius, float angle, Vector3 forward, int layermask = 0)
    {
        FogFill fogfill = new FogFill(this, position, radius, angle, forward);

        ColliderFogRectList colliderrects = GetExtendedColliders(fogfill, layermask);

        if (colliderrects == null)
        {
            fogfill.UnfogCircle(_values);
            return;
        }

        //if (colliderrects.Count != 1 || !colliderrects[0].ContainsCircle(fogfill.position, fogfill.radius))
        //    fogfill.UnfogCircle(_values, colliderrects);
        fogfill.UnfogCircleLineOfSight(_values, colliderrects, layermask);
    }
Esempio n. 2
0
    ColliderFogRectList GetExtendedColliders(FogFill fogfill, int layermask)
    {
        // quick check to see if all raycasts will hit something
        if (layermask == 0)
        {
            return(null);
        }

        ColliderFogRectList colliderrects = null;

        if (mode == FogOfWarMode.Mode2D)
        {
            // is there anything overlapping with the area?
            Collider2D[] colliders = Physics2D.OverlapCircleAll(fogfill.worldPosition, fogfill.worldRadius, layermask);
            if (colliders.Length == 0)
            {
                return(null);
            }

            // extend the colliders outwards away from the center
            colliderrects = new ColliderFogRectList(this);
            colliderrects.Add(colliders);
        }
        else//if (mode == FogOfWarMode.Mode3D)
        {
            // is there anything overlapping with the area?
            Collider[] colliders = Physics.OverlapSphere(fogfill.worldPosition, fogfill.worldRadius, layermask);
            if (colliders.Length == 0)
            {
                return(null);
            }

            // extend the colliders outwards away from the center
            colliderrects = new ColliderFogRectList(this);
            colliderrects.Add(colliders);
        }

        colliderrects.ExtendToCircleEdge(fogfill.position, fogfill.radius);
        colliderrects.Optimise();
        return(colliderrects.Count == 0 ? null : colliderrects);
    }
Esempio n. 3
0
    public void UnfogCircleLineOfSight(byte[] values, ColliderFogRectList excluderects, int layermask)
    {
        for (int y = yStart; y < yEnd; ++y)
        {
            for (int x = xStart; x < xEnd; ++x)
            {
                int index = y * fogOfWar.mapResolution + x;

                // do nothing if it is already completely unfogged
                if (values[index] == 0)
                {
                    continue;
                }

                Vector2i offset = new Vector2i(x - position.x, y - position.y);

                // do nothing if too far too see
                int sqrdistance = offset.sqrMagnitude;
                if (sqrdistance >= radiusSqr)
                {
                    continue;
                }

                // is this point in the view cone?
                Vector2 dir = offset.normalized;
                if (!IsInViewCone(dir))
                {
                    continue;
                }

                // if it could be hidden, raycast to make sure
                if (excluderects.Contains(new Vector2i(x, y)))
                {
                    // perform raycast
                    float hitdistance;
                    if (Raycast(sqrdistance, offset, layermask, out hitdistance))
                    {
                        // optimisation
                        if (fogOfWar.fieldOfViewPenetration == 0.0f)
                        {
                            continue;
                        }

                        // offset the pixel back so that we can see what we are looking at
                        // TODO: This could be optimised by keeping it as ints
                        float pixeldistsqr = new Vector2(offset.x * fogOfWar.pixelSize, offset.y * fogOfWar.pixelSize).sqrMagnitude;
                        float penetration  = Mathf.Min(hitdistance + fogOfWar.fieldOfViewPenetration, worldRadius);
                        if (pixeldistsqr >= penetration * penetration)
                        {
                            continue;
                        }
                    }
                }

                // fully unfogged
                if (sqrdistance <= innerRadiusSqr)
                {
                    values[index] = 0;
                }

                // partially fogged (lerp between innerradius and radius)
                else// if (sqrdistance <= radiusSqr)
                {
                    float t = (Mathf.Sqrt(sqrdistance) - innerRadius) / (radius - innerRadius);
                    byte  v = (byte)Mathf.Lerp(0, 255, t);
                    if (v < values[index])
                    {
                        values[index] = v;
                    }
                }
            }
        }
    }