Files
ADOFAIRenderer/UI/DebugMonitorUI.cs
T

235 lines
10 KiB
C#

using System;
using System.Text;
using ADOFAIRenderer.Component;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace ADOFAIRenderer.UI
{
public class DebugMonitorUI : MonoBehaviour
{
// --- Progress Bar UI Configuration Constants ---
private const float BarWidth = 800f;
private const float BarHeight = 28f;
private const float BarPosX = 0f;
private const float BarPosY = -420f; // Y position relative to screen center (Reference: 1920x1080)
private const int BarTextFontSize = 16; // 눈에 띄게 증가된 텍스트 크기
private static readonly Color BarBackgroundColor = new Color(0.08f, 0.08f, 0.1f, 0.7f);
private static readonly Color BarFillColor = new Color(0.0f, 0.8f, 1.0f, 1.0f); // Sleek cyan/blue
private static readonly Color BarTextColor = new Color(1.0f, 1.0f, 1.0f, 0.7f);
// --- Progress Bar Outline Configuration Constants ---
private static readonly Color BarOutlineColor = Color.white; // 대비되는 흰색 윤곽선
private static readonly Vector2 BarOutlineDistance = new Vector2(3.0f, -3.0f); // 3px의 굵고 직관적인 윤곽선 두께
private TextMeshProUGUI _text = null!;
private GameObject _progressBarObj = null!;
private GameObject _progressBarFillObj = null!;
private RectTransform _fillRect = null!;
private TextMeshProUGUI _progressText = null!;
private static TMP_FontAsset GetNanumSquareNeoBdFontAsset()
{
TMP_FontAsset? font = null;
if (RenderMod.FontBundle != null)
{
try
{
font = RenderMod.FontBundle.LoadAsset<TMP_FontAsset>("NanumSquareNeoOTF-Bd SDF");
}
catch
{
// 로딩 실패
}
}
// 폴백 처리: 에셋 번들에서 실패 시 게임 자체 NanumSquareNeo 또는 내장 TMP SDF 폰트 사용
if (font == null)
{
font = RDString.fontData.fontTMP;
}
if (font == null)
{
// ReSharper disable once Unity.UnknownResource
font = Resources.Load<TMP_FontAsset>("Fonts & Materials/LiberationSans SDF");
}
if (font != null) return font;
var fonts = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
if (fonts.Length > 0) font = fonts[0];
return font!;
}
private void Start()
{
// UI 레이어(5) 설정
gameObject.layer = 5;
// Canvas 설정
var canvas = gameObject.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
canvas.sortingOrder = 9999;
// 해상도 다이내믹 스케일링 설정 (Reference: 1920x1080)
var scaler = gameObject.AddComponent<CanvasScaler>();
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
scaler.referenceResolution = new Vector2(1920, 1080);
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
scaler.matchWidthOrHeight = 0.5f;
gameObject.AddComponent<GraphicRaycaster>();
// 배경 패널 생성
GameObject panelObj = new GameObject("BackgroundPanel");
panelObj.transform.SetParent(transform, false);
panelObj.layer = 5;
var image = panelObj.AddComponent<Image>();
image.color = new Color(0.08f, 0.08f, 0.1f, 0.88f); // 약간 더 고급스러운 다크톤 아크릴 감성
var panelRect = panelObj.GetComponent<RectTransform>();
panelRect.anchorMin = new Vector2(1, 1);
panelRect.anchorMax = new Vector2(1, 1);
panelRect.pivot = new Vector2(1, 1);
panelRect.anchoredPosition = new Vector2(-30, -30);
panelRect.sizeDelta = new Vector2(340, 250);
// 텍스트 생성
var textObj = new GameObject("MonitorText");
textObj.transform.SetParent(panelObj.transform, false);
textObj.layer = 5;
_text = textObj.AddComponent<TextMeshProUGUI>();
_text.richText = true;
_text.fontSize = 16; // 13에서 16으로 증가
_text.alignment = TextAlignmentOptions.TopLeft;
// TMPro 텍스트 잘림 현상 예방
_text.textWrappingMode = TextWrappingModes.Normal;
_text.overflowMode = TextOverflowModes.Overflow;
// NanumSquareNeo-Bd SDF 폰트 로드 및 적용
var font = GetNanumSquareNeoBdFontAsset();
_text.font = font;
var textRect = textObj.GetComponent<RectTransform>();
textRect.anchorMin = Vector2.zero;
textRect.anchorMax = Vector2.one;
textRect.offsetMin = new Vector2(20, 20); // 좀 더 넉넉하고 패딩 여백
textRect.offsetMax = new Vector2(-20, -20);
// --- Progress Bar UI Setup ---
// 1. Progress Bar Container
_progressBarObj = new GameObject("ProgressBar");
_progressBarObj.transform.SetParent(transform, false);
_progressBarObj.layer = 5;
var bgImage = _progressBarObj.AddComponent<Image>();
bgImage.color = BarBackgroundColor;
// 프로그레스 바 흰색 윤곽선 컴포넌트 추가
var bgOutline = _progressBarObj.AddComponent<Outline>();
bgOutline.effectColor = BarOutlineColor;
bgOutline.effectDistance = BarOutlineDistance;
var barRect = _progressBarObj.GetComponent<RectTransform>();
barRect.anchorMin = new Vector2(0.5f, 0.5f);
barRect.anchorMax = new Vector2(0.5f, 0.5f);
barRect.pivot = new Vector2(0.5f, 0.5f);
barRect.anchoredPosition = new Vector2(BarPosX, BarPosY);
barRect.sizeDelta = new Vector2(BarWidth, BarHeight);
// 2. Progress Bar Fill
_progressBarFillObj = new GameObject("ProgressBarFill");
_progressBarFillObj.transform.SetParent(_progressBarObj.transform, false);
_progressBarFillObj.layer = 5;
var fillImage = _progressBarFillObj.AddComponent<Image>();
fillImage.color = BarFillColor;
_fillRect = _progressBarFillObj.GetComponent<RectTransform>();
_fillRect.anchorMin = new Vector2(0, 0);
_fillRect.anchorMax = new Vector2(0, 1);
_fillRect.pivot = new Vector2(0, 0.5f);
_fillRect.anchoredPosition = Vector2.zero;
_fillRect.sizeDelta = new Vector2(0, 0); // width will be updated dynamically in Update()
// 3. Progress Bar Text
var progressTextObj = new GameObject("ProgressBarText");
progressTextObj.transform.SetParent(_progressBarObj.transform, false);
progressTextObj.layer = 5;
_progressText = progressTextObj.AddComponent<TextMeshProUGUI>();
_progressText.richText = true;
_progressText.fontSize = BarTextFontSize; // 14에서 18로 증가
_progressText.alignment = TextAlignmentOptions.Center;
_progressText.font = font;
_progressText.color = BarTextColor;
// 프로그레스 바 내부 텍스트 아웃라인 추가 (진행율 가독성 확보)
var textOutline = progressTextObj.AddComponent<Outline>();
textOutline.effectColor = new Color(0f, 0f, 0f, 0.9f);
textOutline.effectDistance = new Vector2(1.5f, -1.5f);
var textRectBar = progressTextObj.GetComponent<RectTransform>();
textRectBar.anchorMin = Vector2.zero;
textRectBar.anchorMax = Vector2.one;
textRectBar.offsetMin = Vector2.zero;
textRectBar.offsetMax = Vector2.zero;
}
private void Update()
{
if (!_text) return;
var sb = new StringBuilder();
sb.AppendLine("<b><color=#00ccff>ADOFAI Renderer Realtime Monitor</color></b>");
sb.AppendLine();
sb.AppendLine($"• Rendered Progress: <b>{(RenderManager.Instance ? RenderManager.Instance.frameCount : 0)}</b> frames");
var queueCount = 0;
if (RenderManager.Instance)
{
lock (RenderManager.Instance.ImageQueue)
{
queueCount = RenderManager.Instance.ImageQueue.Count;
}
}
sb.AppendLine($"• Queued Buffers: <b>{queueCount}</b> / 60 frames");
sb.AppendLine(RenderMod.IsThrottling
? "• Status: <b><color=yellow>THROTTLING (Safe Mode)</color></b>"
: "• Status: <b><color=green>NORMAL (Encoding)</color></b>");
sb.AppendLine();
sb.AppendLine($"• Throttling Controls: {RenderMod.ThrottleCount} times");
sb.AppendLine($"• Readback Hard Failures: <color=#ff3333>{RenderMod.ReadbackFailureCount}</color> times");
sb.AppendLine($"• Render Skip-Retry: {RenderMod.SkipCount} / 60");
var memoryMb = GC.GetTotalMemory(false) / (1024.0 * 1024.0);
sb.AppendLine($"• Mono Heap Memory: {memoryMb:F2} MB");
_text.text = sb.ToString();
// Update Progress Bar
var progress = 0f;
var currentFloor = 0;
var totalFloors = 0;
if (scrController.instance && ADOBase.lm && ADOBase.lm.listFloors != null)
{
currentFloor = scrController.instance.currFloor ? scrController.instance.currFloor.seqID : 0;
totalFloors = ADOBase.lm.listFloors.Count - 1;
if (totalFloors > 0)
{
progress = Mathf.Clamp01((float)currentFloor / totalFloors);
}
}
if (_fillRect) _fillRect.sizeDelta = new Vector2(BarWidth * progress, 0);
if (_progressText) _progressText.text = $"{progress * 100f:F1}% ({currentFloor}/{totalFloors})";
}
}
}