Skip to content

Fog of War

A fog of war layer covers the map in black and uncovers it as the player explores. This page shows how to add one, how the sample characters clear it, and how to clear it from your own scripts.

Concept

Fog of war is a layer type. Give one layer of the map the type Fog Of War and it stops holding tiles. Instead, every cell of that layer stores how dark it is, with a separate value for each quarter of the cell. That is why the edge of an uncovered area looks soft instead of stepping from tile to tile.

A new fog layer covers the whole map. In play mode, code calls RpgMapHelper.RemoveFogOfWar or RpgMapHelper.RemoveFogOfWarWithFade around a position and the fog thins out there. Neither method ever adds fog back, so an area you have seen stays seen for the rest of the session.

The fog is drawn as a black mesh over the map, like any other layer. Only the first Fog Of War layer in the list is used.

Adding a fog layer

  1. Select the map, open the Paint tab and press Edit.
  2. Add a layer to the layer list with the + button. Layers explains the list.
  3. Set the new layer's type to Fog Of War. Use a new, empty layer, because tiles already on a layer turn into random patches of fog.
  4. Give it a Depth smaller than every other layer, so it draws in front of them. The fog demo uses -1.5, with its Overlay layer at -1.
  5. Press Commit, then Reload Map in the Data tab. The fog only shows up once the map has been reloaded.

The whole map turns black in the Scene view, because that is what an untouched fog layer looks like. To see your tiles while you paint, untick the fog layer's visibility box in the layer list. Tick it again before you commit, since the visibility is saved with the map and a hidden fog layer stays hidden in play.

Painting fog

You cannot paint fog. The brush skips Fog Of War layers, in the Scene view and in the in-game editor.

To cover the whole map again after testing, select the fog layer in the Paint tab and press Clear Selected Layer: <name>. On a fog layer, that button fills every cell with full fog instead of emptying it. Clear Map... in the Data tab does the same to the fog layer, along with clearing every other layer.

Clearing fog around the player

Two components in the sample framework clear fog on their own:

Component Field What it does
PlayerController Fog Sight Length Clears fog around the player each time the player moves to another tile, or when the value changes. The default is 5 tiles.
VehicleCharController Max Altitude Sight Length Only for the Aircraft vehicle type. Clears fog around the aircraft while someone flies it, from nothing on the ground up to this many tiles at full height. The default is 10.

Both use RemoveFogOfWarWithFade, so the fog fades out gradually instead of vanishing. Characters and Vehicles covers the rest of their settings.

A map without a fog layer is not a problem for either of them. The call just does nothing.

The fog demo

demo4 - FogOfWar in Samples/Scenes shows all of this. Its map, AutoTileMapData4, has a fourth layer called FogOfWar. The player walks with a sight of 5 tiles, and the balloons are aircraft that uncover up to 10 tiles around them once they are in the air. See Sample Scenes for the controls.

Clearing fog from a script

Both methods are static on RpgMapHelper and take a world position and a sight length:

  • RemoveFogOfWar(Vector3 worldPosition, int sightLength) clears the fog at once.
  • RemoveFogOfWarWithFade(Vector3 worldPosition, int sightLength) fades it out. The fade only runs in play mode.

sightLength is in tiles, not world units. The area is centred on the tile under worldPosition. It is fully clear in the middle and the fog closes in towards the edge, reaching full darkness sightLength tiles away, so the uncovered patch is round. Calling either method again over an area that is already clearer changes nothing there.

This component clears fog around whatever it is attached to, the same way PlayerController does:

using UnityEngine;
using CreativeSpore.RpgMapEditor;

public class RevealFog : MonoBehaviour
{
    // In tiles, not world units.
    public int SightLength = 4;

    int m_lastTileIdx = -1;

    void Update()
    {
        // Only clear again when the object has moved to another tile.
        int tileIdx = RpgMapHelper.GetTileIdxByPosition(transform.position);
        if (tileIdx != m_lastTileIdx)
        {
            RpgMapHelper.RemoveFogOfWarWithFade(transform.position, SightLength);
            m_lastTileIdx = tileIdx;
        }
    }
}

Both methods work on AutoTileMap.Instance, the map currently loaded. Scripting has more on the helper class.

Saving and fog

Fog you uncover in play mode is not saved. When you stop playing, the fog comes back the way it was saved, which normally means fully covered.

Save Changes After Playing does not change that on its own, because uncovering fog does not count as changing a tile. There is one catch. With the toggle on, if a tile does change during the same play session, from the in-game editor or a script, the whole map is saved when you stop, and the fog goes into the Map Data asset exactly as uncovered as it was at that moment. The Save button of the in-game editor writes the fog the same way. If that happens, cover it again with Clear Selected Layer and press Commit.

Before version 1.6.1, Save Changes After Playing saved the map every time play mode ended, so uncovered fog stayed uncovered for good. That no longer happens.

Saving and Loading explains the rest of how maps are saved.