Fog of War(未踏領域の暗転表示)は、戦術性を高めます。
見えない領域があることで、戦略が重要になります。
この記事では、実装方法を詳しく解説します。
✨ この記事でわかること
- Fog of Warの基本概念
- 視界判定システムの実装
- マップ描画システムの実装
- メモリ情報の管理
- 実装例とコード

Fog of Warは、視界判定から始めましょう。ユニットの視界範囲を計算して、マップを更新します。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
Fog of Warの基本概念

Fog of Warは、3つの状態でマップを管理します。
それぞれの状態を理解しましょう。
- 視界内:現在見えている領域(明るい)
- 未探索:一度も見たことがない領域(暗い)
- 探索済み:以前見たことがあるが、現在は見えない領域(薄暗い)
この3つの状態で、マップを管理します。
視界状態の定義
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public enum FogState { Unexplored, // 未探索(完全に暗い) Explored, // 探索済み(薄暗い) Visible // 視界内(明るい) } public class FogOfWar : MonoBehaviour { public int mapWidth = 100; public int mapHeight = 100; private FogState[,] fogMap; void Start() { fogMap = new FogState[mapWidth, mapHeight]; // 初期状態はすべて未探索 for (int x = 0; x < mapWidth; x++) { for (int y = 0; y < mapHeight; y++) { fogMap[x, y] = FogState.Unexplored; } } } } |
このコードで、Fog of Warの基本構造が実装できます。
マップの各セルに、視界状態を保存します。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
視界判定システムの実装

視界判定は、ユニットの視界範囲を計算します。
実装方法を紹介します。
視界範囲の計算
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
using UnityEngine; using System.Collections.Generic; public class VisionCalculator : MonoBehaviour { public void UpdateVision(List<Unit> units, FogState[,] fogMap) { // 前回の視界をクリア ClearPreviousVision(fogMap); // 各ユニットの視界を計算 foreach (var unit in units) { if (unit.stats.currentHP <= 0) continue; CalculateUnitVision(unit, fogMap); } } void ClearPreviousVision(FogState[,] fogMap) { for (int x = 0; x < fogMap.GetLength(0); x++) { for (int y = 0; y < fogMap.GetLength(1); y++) { if (fogMap[x, y] == FogState.Visible) { fogMap[x, y] = FogState.Explored; } } } } void CalculateUnitVision(Unit unit, FogState[,] fogMap) { int visionRange = unit.stats.visionRange; Vector2Int unitPos = new Vector2Int(unit.gridX, unit.gridY); // 視界範囲内の全セルをチェック for (int x = -visionRange; x <= visionRange; x++) { for (int y = -visionRange; y <= visionRange; y++) { int distance = Mathf.RoundToInt(Vector2.Distance(Vector2.zero, new Vector2(x, y))); if (distance <= visionRange) { int mapX = unitPos.x + x; int mapY = unitPos.y + y; if (IsValidPosition(mapX, mapY, fogMap)) { // 障害物チェック if (!HasObstacle(mapX, mapY)) { fogMap[mapX, mapY] = FogState.Visible; } } } } } } bool IsValidPosition(int x, int y, FogState[,] fogMap) { return x >= 0 && x < fogMap.GetLength(0) && y >= 0 && y < fogMap.GetLength(1); } bool HasObstacle(int x, int y) { // 障害物チェック // 実装は省略 return false; } } |
このコードで、視界判定が実装できます。
ユニットの視界範囲を計算して、マップを更新します。
視界の更新頻度
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class FogOfWarManager : MonoBehaviour { public VisionCalculator visionCalculator; public float updateInterval = 0.5f; // 0.5秒ごとに更新 private float lastUpdateTime = 0f; private FogState[,] fogMap; void Update() { if (Time.time - lastUpdateTime >= updateInterval) { UpdateFogOfWar(); lastUpdateTime = Time.time; } } void UpdateFogOfWar() { List<Unit> allUnits = GetAllUnits(); visionCalculator.UpdateVision(allUnits, fogMap); UpdateMapVisualization(); } void UpdateMapVisualization() { // マップの視覚化を更新 } } |
視界判定を毎フレーム実行せず、一定間隔で更新します。
これにより、負荷を軽減できます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
マップ描画システムの実装

マップ描画は、視界状態に応じて色を変えます。
実装方法を紹介します。
2Dマップの描画
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using UnityEngine; public class FogOfWarRenderer : MonoBehaviour { public Material fogMaterial; public Texture2D fogTexture; public void RenderFogOfWar(FogState[,] fogMap) { int width = fogMap.GetLength(0); int height = fogMap.GetLength(1); Color[] colors = new Color[width * height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int index = y * width + x; colors[index] = GetFogColor(fogMap[x, y]); } } fogTexture.SetPixels(colors); fogTexture.Apply(); } Color GetFogColor(FogState state) { switch (state) { case FogState.Unexplored: return Color.black; // 完全に暗い case FogState.Explored: return new Color(0.2f, 0.2f, 0.2f, 1f); // 薄暗い case FogState.Visible: return Color.clear; // 明るい(透明) default: return Color.black; } } } |
このコードで、2Dマップの描画が実装できます。
視界状態に応じて、色を変更します。
3Dマップの描画
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
public class FogOfWarRenderer3D : MonoBehaviour { public GameObject fogPlanePrefab; private GameObject[,] fogPlanes; public void RenderFogOfWar3D(FogState[,] fogMap) { int width = fogMap.GetLength(0); int height = fogMap.GetLength(1); if (fogPlanes == null) { fogPlanes = new GameObject[width, height]; CreateFogPlanes(width, height); } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { UpdateFogPlane(x, y, fogMap[x, y]); } } } void CreateFogPlanes(int width, int height) { for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Vector3 position = new Vector3(x, 0.1f, y); GameObject plane = Instantiate(fogPlanePrefab, position, Quaternion.identity); fogPlanes[x, y] = plane; } } } void UpdateFogPlane(int x, int y, FogState state) { GameObject plane = fogPlanes[x, y]; Renderer renderer = plane.GetComponent<Renderer>(); Color color = GetFogColor(state); renderer.material.color = color; // 視界内の場合は非表示 plane.SetActive(state != FogState.Visible); } } |
3Dマップの描画も実装できます。
各セルにフォグプレーンを配置して、視界状態に応じて色を変更します。

マップ描画は、視界状態に応じて色を変えるだけです。シェーダーを使えば、より滑らかな表現ができます。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
メモリ情報の管理

探索済み領域には、以前見た情報を表示します。
実装方法を紹介します。
メモリ情報の保存
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
using UnityEngine; using System.Collections.Generic; public class MemoryManager : MonoBehaviour { private Dictionary<Vector2Int, MemoryData> memoryMap = new Dictionary<Vector2Int, MemoryData>(); public void SaveMemory(Vector2Int position, MemoryData data) { if (!memoryMap.ContainsKey(position)) { memoryMap[position] = data; } else { // 既存の情報を更新(最新の情報を優先) memoryMap[position] = data; } } public MemoryData GetMemory(Vector2Int position) { if (memoryMap.ContainsKey(position)) { return memoryMap[position]; } return null; } public void UpdateMemoryFromVision(FogState[,] fogMap) { for (int x = 0; x < fogMap.GetLength(0); x++) { for (int y = 0; y < fogMap.GetLength(1); y++) { if (fogMap[x, y] == FogState.Visible) { Vector2Int pos = new Vector2Int(x, y); MemoryData data = GetCurrentMapData(pos); SaveMemory(pos, data); } } } } MemoryData GetCurrentMapData(Vector2Int position) { // 現在のマップデータを取得 MemoryData data = new MemoryData(); // 実装は省略 return data; } } [System.Serializable] public class MemoryData { public TileType tileType; public List<Unit> units; public List<Building> buildings; } |
このコードで、メモリ情報の管理が実装できます。
視界内の情報を保存して、探索済み領域に表示します。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
実装例:完全なFog of Warシステム

実際に使える、完全なFog of Warシステムの実装例を紹介します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
using UnityEngine; using System.Collections.Generic; public class CompleteFogOfWarSystem : MonoBehaviour { [Header("システム")] public VisionCalculator visionCalculator; public FogOfWarRenderer fogRenderer; public MemoryManager memoryManager; [Header("設定")] public int mapWidth = 100; public int mapHeight = 100; public float updateInterval = 0.5f; private FogState[,] fogMap; private float lastUpdateTime = 0f; void Start() { InitializeFogOfWar(); } void InitializeFogOfWar() { fogMap = new FogState[mapWidth, mapHeight]; // 初期状態はすべて未探索 for (int x = 0; x < mapWidth; x++) { for (int y = 0; y < mapHeight; y++) { fogMap[x, y] = FogState.Unexplored; } } } void Update() { if (Time.time - lastUpdateTime >= updateInterval) { UpdateFogOfWar(); lastUpdateTime = Time.time; } } void UpdateFogOfWar() { // 1. 視界を計算 List<Unit> allUnits = GetAllUnits(); visionCalculator.UpdateVision(allUnits, fogMap); // 2. メモリを更新 memoryManager.UpdateMemoryFromVision(fogMap); // 3. マップを描画 fogRenderer.RenderFogOfWar(fogMap); } List<Unit> GetAllUnits() { // 全ユニットを取得 return new List<Unit>(); } } |
このコードで、完全なFog of Warシステムが実装できます。
視界判定、マップ描画、メモリ管理を統合しています。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
よくある質問(FAQ)

Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる
あなたのオリジナルゲーム、今年こそ完成させませんか?
RPG・アクション・ホラー…Unityで本格ゲームを作りたい人のための学習サイトです。
実際に完成するゲームを題材に、
ソースコード・素材・プロジェクト一式をすべて公開。
仕事や学校の合間の1〜2時間でも、
「写経→改造」で自分のゲームまで作りきれる環境です。
まとめ

Fog of Warは、視界判定から始めましょう。
マップ描画とメモリ管理を組み合わせることで、戦術性が高まります。
✅ 今日から始める3ステップ
- ステップ1:視界判定システムを実装する(所要2時間)
- ステップ2:マップ描画システムを実装する(所要2時間)
- ステップ3:メモリ管理システムを実装する(所要2時間)
本格的にUnityを学びたい方は、Unity入門の森で実践的なスキルを身につけましょう。
あなたのペースで、少しずつ進めていけば大丈夫です。
Unity入門の森を見る 初心者歓迎!動画×プロジェクト一式で本格ゲーム制作を学べる



コメント