Files
ProjectMD/Assets/Scripts/GameBase/FogOfWar.cs
Dal4segno b4ac8f600f 전장의 안개 로직 개선
미탐험지역은 검게 덮음. 탐험된 지역은 어두운 색, 보고 있는 블록은 밝은색
2026-01-18 23:37:43 +09:00

88 lines
3.2 KiB
C#

using UnityEngine;
using Unity.Netcode;
public class FogOfWarManager : MonoBehaviour
{
public static FogOfWarManager Instance;
[Header("Settings")]
public float worldSize = 100f; // 1단계에서 만든 Plane의 크기와 맞춤
public int textureSize = 512; // 안개 해상도 (높을수록 부드러움)
public float revealRadius = 5f; // 밝혀지는 반경
[Header("Underground Settings")]
public float groundLevelY = 0f; // 이 높이보다 낮으면 지하로 간주
private Texture2D _fogTexture;
private Color32[] _pixels;
void Awake()
{
Instance = this;
InitTexture();
}
private void InitTexture()
{
// 1. 텍스처 생성 (모두 검은색으로 시작)
_fogTexture = new Texture2D(textureSize, textureSize, TextureFormat.RGBA32, false);
_pixels = new Color32[textureSize * textureSize];
for (int i = 0; i < _pixels.Length; i++) _pixels[i] = new Color32(0, 0, 0, 255);
_fogTexture.SetPixels32(_pixels);
_fogTexture.Apply();
// 2. 셰이더 전역 변수로 전달 (이름이 중요!)
Shader.SetGlobalTexture("_GlobalFogTex", _fogTexture);
Shader.SetGlobalFloat("_FogWorldSize", worldSize);
// 셰이더에 기준 높이 전달
Shader.SetGlobalFloat("_GroundLevelY", groundLevelY);
}
void Update()
{
if (NetworkManager.Singleton != null && NetworkManager.Singleton.LocalClient != null)
{
var localPlayer = NetworkManager.Singleton.LocalClient.PlayerObject;
if (localPlayer != null)
{
UpdateFogMask(localPlayer.transform.position);
// 추가: 플레이어가 지상에 있을 때는 안개 판을 아예 꺼버릴 수도 있습니다 (선택 사항)
// bool isUnderground = localPlayer.transform.position.y < groundLevelY + 2f;
// fogOverlayObject.SetActive(isUnderground);
}
}
}
private void UpdateFogMask(Vector3 playerPos)
{
// 월드 좌표를 텍스처 좌표로 변환
int centerX = Mathf.RoundToInt((playerPos.x / worldSize + 0.5f) * textureSize);
int centerZ = Mathf.RoundToInt((playerPos.z / worldSize + 0.5f) * textureSize);
int radius = Mathf.RoundToInt((revealRadius / worldSize) * textureSize);
bool changed = false;
for (int y = centerZ - radius; y <= centerZ + radius; y++)
{
for (int x = centerX - radius; x <= centerX + radius; x++)
{
if (x >= 0 && x < textureSize && y >= 0 && y < textureSize)
{
float dist = Vector2.Distance(new Vector2(x, y), new Vector2(centerX, centerZ));
if (dist < radius)
{
int idx = y * textureSize + x;
if (_pixels[idx].a != 0)
{ // 아직 안 밝혀진 곳만
_pixels[idx] = new Color32(0, 0, 0, 0); // 투명하게!
changed = true;
}
}
}
}
}
if (changed) { _fogTexture.SetPixels32(_pixels); _fogTexture.Apply(); }
}
}