88 lines
3.2 KiB
C#
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(); }
|
|
}
|
|
} |