Files
DTrierFlood_New/Assets/Scripts/Debug/RuntimeBootProbe.cs

225 lines
7.9 KiB
C#

using System;
using System.IO;
using System.Reflection;
using System.Text;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
[DisallowMultipleComponent]
public sealed class RuntimeBootProbe : MonoBehaviour
{
[Header("Optional References")]
[SerializeField] private GameObject hudRoot;
[SerializeField] private GeoTileAddressablesLoader geoTileLoader;
[SerializeField] private Transform expectedPlayer;
[Header("Probe Settings")]
[SerializeField] private bool logOnAwake = true;
[SerializeField] private bool logOnStart = true;
[SerializeField] private bool logAfterDelay = true;
[SerializeField] private float delayedLogSeconds = 2.0f;
private void Awake()
{
if (logOnAwake)
Dump("Awake");
}
private void Start()
{
if (logOnStart)
Dump("Start");
if (logAfterDelay && delayedLogSeconds > 0.0f)
Invoke(nameof(DumpDelayed), delayedLogSeconds);
}
private void DumpDelayed()
{
Dump("Delayed");
}
private void Dump(string phase)
{
var sb = new StringBuilder(1024);
sb.Append("[RuntimeBootProbe] ").Append(phase).Append(" ");
sb.Append("activeScene=").Append(SceneManager.GetActiveScene().name).Append(" ");
sb.Append("loadedScenes=").Append(SceneManager.sceneCount).Append(" ");
sb.Append("persistentDataPath=").Append(Application.persistentDataPath).Append(" ");
if (hudRoot == null)
{
sb.Append("hudRoot=null ");
}
else
{
sb.Append("hudRoot.activeInHierarchy=").Append(hudRoot.activeInHierarchy).Append(" ");
sb.Append("hudRoot.activeSelf=").Append(hudRoot.activeSelf).Append(" ");
}
if (expectedPlayer == null)
{
sb.Append("expectedPlayer=null ");
}
else
{
Vector3 p = expectedPlayer.position;
sb.Append("expectedPlayer.pos=(")
.Append(p.x.ToString("F2")).Append(",")
.Append(p.y.ToString("F2")).Append(",")
.Append(p.z.ToString("F2")).Append(") ");
}
if (geoTileLoader == null)
{
sb.Append("geoTileLoader=null ");
AppendRenderState(sb);
Debug.Log(sb.ToString());
return;
}
bool loaderEnabled = geoTileLoader.enabled && geoTileLoader.gameObject.activeInHierarchy;
sb.Append("geoTileLoader.enabled=").Append(loaderEnabled).Append(" ");
string tileBundleFolderName = ReadPrivateField(geoTileLoader, "tileBundleFolderName", "TileBundles");
string manifestFileName = ReadPrivateField(geoTileLoader, "manifestFileName", "TileManifest.json");
string buildingManifestFileName = ReadPrivateField(geoTileLoader, "buildingManifestFileName", "TileBuildingsManifest.json");
string buildTargetFolderOverride = ReadPrivateField(geoTileLoader, "buildTargetFolderOverride", "");
string buildTargetFolder = string.IsNullOrWhiteSpace(buildTargetFolderOverride)
? GetBuildTargetFolderName()
: buildTargetFolderOverride;
string basePath = Path.Combine(Application.persistentDataPath, tileBundleFolderName, buildTargetFolder);
string manifestPath = Path.Combine(basePath, manifestFileName);
string buildingsManifestPath = Path.Combine(basePath, buildingManifestFileName);
string catalogPath = ResolveCatalogPath(manifestPath);
sb.Append("basePath=").Append(basePath).Append(" ");
sb.Append("manifestExists=").Append(File.Exists(manifestPath)).Append(" ");
sb.Append("buildingsManifestExists=").Append(File.Exists(buildingsManifestPath)).Append(" ");
if (!string.IsNullOrWhiteSpace(catalogPath))
sb.Append("catalogExists=").Append(File.Exists(catalogPath)).Append(" ");
else
sb.Append("catalogExists=unknown ");
AppendRenderState(sb);
Debug.Log(sb.ToString());
}
private static void AppendRenderState(StringBuilder sb)
{
var rp = GraphicsSettings.currentRenderPipeline;
string rpName = rp != null ? $"{rp.name} ({rp.GetType().Name})" : "BuiltInRenderPipeline";
int qualityIndex = QualitySettings.GetQualityLevel();
string qualityName = qualityIndex >= 0 && qualityIndex < QualitySettings.names.Length
? QualitySettings.names[qualityIndex]
: "<unknown>";
sb.Append("quality=").Append(qualityIndex).Append(":").Append(qualityName).Append(" ");
sb.Append("renderPipeline=").Append(rpName).Append(" ");
var cam = Camera.main;
if (cam == null)
{
sb.Append("mainCamera=<none> ");
}
else
{
sb.Append("mainCamera=").Append(cam.name).Append(" ");
sb.Append("mainCamera.farClip=").Append(cam.farClipPlane.ToString("F1")).Append(" ");
sb.Append("mainCamera.nearClip=").Append(cam.nearClipPlane.ToString("F3")).Append(" ");
sb.Append("mainCamera.cullingMask=0x").Append(cam.cullingMask.ToString("X")).Append(" ");
}
AppendXrState(sb);
}
private static void AppendXrState(StringBuilder sb)
{
try
{
Type xrSettingsType = Type.GetType("UnityEngine.XR.XRSettings, UnityEngine.XRModule");
if (xrSettingsType == null)
{
sb.Append("xrEnabled=<unavailable> ");
return;
}
var enabledProp = xrSettingsType.GetProperty("enabled", BindingFlags.Public | BindingFlags.Static);
bool xrEnabled = enabledProp != null && enabledProp.GetValue(null) is bool enabled && enabled;
sb.Append("xrEnabled=").Append(xrEnabled).Append(" ");
if (!xrEnabled)
return;
var stereoModeProp = xrSettingsType.GetProperty("stereoRenderingMode", BindingFlags.Public | BindingFlags.Static);
object stereoMode = stereoModeProp?.GetValue(null);
sb.Append("xrStereoMode=").Append(stereoMode != null ? stereoMode.ToString() : "<unknown>").Append(" ");
}
catch
{
sb.Append("xrEnabled=<error> ");
}
}
private static string ReadPrivateField(GeoTileAddressablesLoader loader, string fieldName, string fallback)
{
try
{
FieldInfo fi = typeof(GeoTileAddressablesLoader).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
if (fi == null)
return fallback;
object value = fi.GetValue(loader);
return value as string ?? fallback;
}
catch
{
return fallback;
}
}
private static string ResolveCatalogPath(string manifestPath)
{
try
{
if (!File.Exists(manifestPath))
return null;
string json = File.ReadAllText(manifestPath);
TileManifest manifest = JsonUtility.FromJson<TileManifest>(json);
if (manifest == null || string.IsNullOrWhiteSpace(manifest.catalogFile))
return null;
return Path.Combine(Path.GetDirectoryName(manifestPath) ?? string.Empty, manifest.catalogFile);
}
catch
{
return null;
}
}
private static string GetBuildTargetFolderName()
{
switch (Application.platform)
{
case RuntimePlatform.Android:
return "Android";
case RuntimePlatform.WindowsPlayer:
case RuntimePlatform.WindowsEditor:
return "StandaloneWindows64";
case RuntimePlatform.OSXPlayer:
case RuntimePlatform.OSXEditor:
return "StandaloneOSX";
case RuntimePlatform.LinuxPlayer:
case RuntimePlatform.LinuxEditor:
return "StandaloneLinux64";
default:
return "Android";
}
}
}