SHA256
235 lines
10 KiB
C#
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})";
|
|
}
|
|
}
|
|
}
|