/* ┌──────────────────────────────────────────────────────────────────┐ │ Author: Ivan Murzak (https://github.com/IvanMurzak) │ │ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │ │ Copyright (c) 2025 Ivan Murzak │ │ Licensed under the Apache License, Version 2.0. │ │ See the LICENSE file in the project root for more information. │ └──────────────────────────────────────────────────────────────────┘ */ #nullable enable using System.Collections.Generic; using System.ComponentModel; using com.IvanMurzak.McpPlugin; namespace com.IvanMurzak.Unity.MCP.Editor.API { [AiToolType] public partial class Tool_Profiler { /// /// Default-enabled subset of . Mutated by /// profiler-enable-module and read by profiler-get-status / /// profiler-list-modules. Unity's runtime Profiler API does not expose /// per-module enable/disable, so this is purely a bookkeeping helper for callers; /// actual module visibility is controlled from the Profiler window. /// internal static readonly HashSet EnabledModules = new HashSet() { "CPU", "GPU", "Rendering", "Memory", "Audio", "Video", "Physics", "Physics2D", "UI" }; /// /// Canonical list of profiler module names this tool surface understands. Derived /// from the names Unity uses in its built-in Profiler window — kept here as a /// constant so the wrapper is independent of the optional /// `com.unity.profiling.core` package (per task scope, the core tool must rely on /// built-in Unity APIs only). Exposed as so callers /// cannot accidentally mutate the canonical list via .Add(). /// internal static readonly IReadOnlyList AvailableModules = new List() { "CPU", "GPU", "Rendering", "Memory", "Audio", "Video", "Physics", "Physics2D", "NetworkMessages", "NetworkOperations", "UI", "UIDetails", "GlobalIllumination", "VirtualTexturing" }.AsReadOnly(); public static class Error { public static string ModuleNameIsRequired() => "[Error] Module name is required."; public static string UnknownModule(string moduleName) => $"[Error] Unknown profiler module: '{moduleName}'. Available modules: {string.Join(", ", AvailableModules)}"; public static string FilePathIsRequired() => "[Error] File path is required."; public static string FileNotFound(string filePath) => $"[Error] Profiler data file not found: '{filePath}'."; public static string FileTooLarge(string filePath, long fileBytes, long maxBytes) => $"[Error] Profiler data file '{filePath}' is {fileBytes} bytes, exceeding the {maxBytes}-byte cap."; public static string FailedToSaveData(string message) => $"[Error] Failed to save profiler data: {message}"; public static string FailedToLoadData(string message) => $"[Error] Failed to load profiler data: {message}"; } [Description("Profiler status data including memory and module information.")] public class ProfilerStatusData { [Description("Whether Unity's runtime profiler is currently enabled (UnityEngine.Profiling.Profiler.enabled).")] public bool ProfilerEnabled { get; set; } [Description("List of profiler modules this wrapper considers active. Local bookkeeping only.")] public List? ActiveModules { get; set; } [Description("Maximum used memory recorded by the profiler, in megabytes.")] public float MaxUsedMemoryMB { get; set; } [Description("Whether profiling is supported on this platform (UnityEngine.Profiling.Profiler.supported).")] public bool Supported { get; set; } } [Description("Memory statistics from the Unity Profiler. All values in megabytes unless otherwise noted.")] public class MemoryStatsData { [Description("Total reserved memory (UnityEngine.Profiling.Profiler.GetTotalReservedMemoryLong / 1048576).")] public float TotalReservedMemoryMB { get; set; } [Description("Total allocated memory (UnityEngine.Profiling.Profiler.GetTotalAllocatedMemoryLong / 1048576).")] public float TotalAllocatedMemoryMB { get; set; } [Description("Total unused reserved memory (UnityEngine.Profiling.Profiler.GetTotalUnusedReservedMemoryLong / 1048576).")] public float TotalUnusedReservedMemoryMB { get; set; } [Description("Mono heap size (UnityEngine.Profiling.Profiler.GetMonoHeapSizeLong / 1048576).")] public float MonoHeapSizeMB { get; set; } [Description("Mono used size (UnityEngine.Profiling.Profiler.GetMonoUsedSizeLong / 1048576).")] public float MonoUsedSizeMB { get; set; } [Description("Temp allocator size (UnityEngine.Profiling.Profiler.GetTempAllocatorSize / 1048576).")] public float TempAllocatorSizeMB { get; set; } [Description("Graphics memory reserved by the driver (UnityEngine.Profiling.Profiler.GetAllocatedMemoryForGraphicsDriver / 1048576).")] public float GraphicsMemoryMB { get; set; } [Description("Maximum used memory observed (UnityEngine.Profiling.Profiler.maxUsedMemory / 1048576).")] public float MaxUsedMemoryMB { get; set; } [Description("Used heap size (UnityEngine.Profiling.Profiler.usedHeapSizeLong / 1048576).")] public float UsedHeapSizeMB { get; set; } } [Description("Rendering statistics from Unity's Time / QualitySettings / SystemInfo. No external package required.")] public class RenderingStatsData { [Description("Last reported frame time (Time.deltaTime * 1000) in milliseconds.")] public float FrameTimeMs { get; set; } [Description("Frames per second derived from Time.deltaTime.")] public float Fps { get; set; } [Description("QualitySettings.vSyncCount.")] public int VSyncCount { get; set; } [Description("Application.targetFrameRate.")] public int TargetFrameRate { get; set; } [Description("SystemInfo.renderingThreadingMode.")] public string? RenderingThreadingMode { get; set; } [Description("SystemInfo.graphicsDeviceType.")] public string? GraphicsDeviceType { get; set; } } [Description("Script statistics derived from UnityEngine.Time + UnityEngine.Profiling.Profiler.")] public class ScriptStatsData { [Description("Time.deltaTime in milliseconds.")] public float FrameTimeMs { get; set; } [Description("Time.fixedDeltaTime in milliseconds.")] public float FixedDeltaTimeMs { get; set; } [Description("Time.timeScale.")] public float TimeScale { get; set; } [Description("Total frame count since application start (Time.frameCount).")] public int TotalFrameCount { get; set; } [Description("Time.realtimeSinceStartup, in seconds.")] public float RealtimeSinceStartup { get; set; } [Description("Mono used size (Profiler.GetMonoUsedSizeLong / 1048576), in megabytes.")] public float MonoMemoryUsageMB { get; set; } [Description("System.GC.GetTotalMemory(false) / 1048576, in megabytes.")] public float GCMemoryUsageMB { get; set; } } [Description("Single-frame snapshot of timing information from UnityEngine.Time. No historical frame data; use the Profiler window for that.")] public class FrameCaptureData { [Description("Time.deltaTime in milliseconds at the moment of capture.")] public float FrameTimeMs { get; set; } [Description("Frames per second derived from Time.deltaTime.")] public float Fps { get; set; } [Description("Total frame count since application start (Time.frameCount). May include skipped renders.")] public int TotalFrameCount { get; set; } [Description("Time.realtimeSinceStartup, in seconds.")] public float RealtimeSinceStartup { get; set; } [Description("Frames actually rendered (Time.renderedFrameCount).")] public int RenderedFrameCount { get; set; } } [Description("Profiler module entry returned by 'profiler-list-modules'.")] public class ProfilerModuleInfo { [Description("Module name (e.g. 'CPU', 'Memory').")] public string? Name { get; set; } [Description("Whether the wrapper considers this module enabled. Local bookkeeping only.")] public bool Enabled { get; set; } } [Description("Container for 'profiler-list-modules' output.")] public class ProfilerModulesData { [Description("All known profiler modules and their wrapper-side enabled flag.")] public List? Modules { get; set; } } } }