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(); } } }