Finally done with Line of Sight (kinda)


So, here's the ultimate problem I had with my line of sight code.  (I'll post my code at the end of this).

In C# Math.Sign(0) returns 0.  

In Unity Mathf.Sign(0) returns 1.

Why?  My guess is just to annoy me.  I don't know many people who even use that as a function.  But I do, and that difference between 1 and 0 seriously ruined my calculations because it put whole rows and columns of calculations one step off.

But it's working now.  The problem I have is that I need to find a way to move a light, or turn it off, and still have other lights in the area stay on.  But since I don't have multiple lights in the game right now, I don't have to worry about it today.

If you're interested, I call illumination when I have a light source move, and I have a 'darken' command to subtract light when it's not in an area anymore.  

There is probably a way to do the r/x coordinates better.  And I'm not a huge fan of passing the Source every time (I'm thinking about making a 'light object' and passing that in for ease.)


 public void Illuminate(int SourceX, int SourceY, float Intensity, int Range)
    {
        // Should I ask for source game object?  See if it has illumination settings?  The player could work this way....
        // I should create a light source class and jam all this in that, then just pass in a class when it's time to work.         LightSourceX = SourceX;
        LightSourceY = SourceY;         LightSourceIntensity = Intensity;
        LightSourceRange = Range;
        
        GameObject TargetObject = GetTileAt(SourceX, SourceY);         Tile TargetTile = TargetObject.GetComponent<Tile>();
        //TargetTile.ExternalIllumination += 1.0f;
        //TargetTile.Visibility = 1.0f;
        //TargetTile.ShadeTile();
        if (Intensity != 0.0f)
        {
            for (int r = 1; r <= Range; r++)
            {
                // Shade Cardinals
                LightRay(SourceX, SourceY, r, 0);
                LightRay(SourceX, SourceY, -r, 0);
                LightRay(SourceX, SourceY, 0, r);
                LightRay(SourceX, SourceY, 0, -r);                 // Shade Diagnals
                LightRay(SourceX, SourceY, r, r);
                LightRay(SourceX, SourceY, r, -r);
                LightRay(SourceX, SourceY, -r, r);
                LightRay(SourceX, SourceY, -r, -r);                 // Shade Sectors
                if (r > 1)
                {
                    for (int x = 1; x < r; x++)
                    {
                        // Vertical diagnals
                        LightRay(SourceX, SourceY, r, x);
                        LightRay(SourceX, SourceY, r, -x);
                        LightRay(SourceX, SourceY, -r, x);
                        LightRay(SourceX, SourceY, -r, -x);                         // Horizontal diagnals
                        LightRay(SourceX, SourceY, x, r);
                        LightRay(SourceX, SourceY, x, -r);
                        LightRay(SourceX, SourceY, -x, r);
                        LightRay(SourceX, SourceY, -x, -r);
                    }
                }
            }
        }
    }     public void LightRay(int SourceX, int SourceY, int x, int y)
    {
        GameObject TargetObject = GetTileAt(SourceX + x, SourceY + y);
        
        if (TargetObject != null)
        {
            int MidX = SourceX + (int)((Mathf.Abs(x) - 1) * System.Math.Sign(x)); // Need to use SYSTEM here explicity because Unity's Sign returns zero as 1
            int MidY = SourceY + (int)((Mathf.Abs(y) - 1) * System.Math.Sign(y)); // Need to use SYSTEM here explicity because Unity's Sign returns zero as 1
            //Debug.Log(y.ToString() + "= y should be 0 = " + (int)((Mathf.Abs(y) - 1) * Mathf.Sign(y)));             GameObject MidObject = GetTileAt(MidX, MidY);             if (MidObject != null)
            {
                float Distance = Mathf.Sqrt(Mathf.Pow(Mathf.Abs(MidX - SourceX), 2.0f) + Mathf.Pow(Mathf.Abs(MidY - SourceY), 2));
                float Falloff = (LightSourceIntensity / LightSourceRange) + .1f;
                float Intensity = LightSourceIntensity - (Falloff * Distance);
                
                //Debug.Log("Distance: " + Distance.ToString() + " Falloff: " + Falloff.ToString() + " Intensity: " + Intensity.ToString());                 Tile TargetTile = TargetObject.GetComponent<Tile>();
                Tile MidTile = MidObject.GetComponent<Tile>();                 //TargetTile.Visibility = 1.0f;
                TargetTile.Visibility = Convert.ToInt32(!MidTile.BlocksSight) * MidTile.Visibility;                 //TargetTile.ExternalIllumination += 1.0f;
                TargetTile.ExternalIllumination += Intensity;
                TargetTile.ShadeTile();
            }
            else
            {
                Debug.LogError("Tile at: " + MidX.ToString() + "," + MidY.ToString() + " is null.  This should be impossible!");
            }         }    
    }

Leave a comment

Log in with itch.io to leave a comment.