forked from IvanMurzak/Unity-MCP
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUnityLogger.cs
More file actions
136 lines (121 loc) · 5.64 KB
/
UnityLogger.cs
File metadata and controls
136 lines (121 loc) · 5.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
┌──────────────────────────────────────────────────────────────────┐
│ 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;
using Microsoft.Extensions.Logging;
namespace com.IvanMurzak.Unity.MCP.Utils
{
using LogLevel = Runtime.Utils.LogLevel;
using LogLevelMicrosoft = Microsoft.Extensions.Logging.LogLevel;
public class UnityLogger : ILogger
{
readonly string _categoryName;
readonly string _categoryColor;
// Colors that look good on dark gray background
private static readonly string[] CategoryColors = new[]
{
"#FF6B9D", // Pink
"#4ECDC4", // Teal
"#FFD93D", // Yellow
"#95E1D3", // Mint
"#F38181", // Coral
"#AA96DA", // Purple
"#6BCF7F", // Green
"#5DADE2", // Blue
"#F8B739", // Orange
"#EC7063", // Red
"#48C9B0", // Turquoise
"#AF7AC5", // Violet
"#58D68D", // Lime
"#F5B041", // Amber
"#85C1E2" // Sky Blue
};
public UnityLogger(string categoryName)
{
_categoryName = categoryName.Contains('.')
? categoryName.Substring(categoryName.LastIndexOf('.') + 1)
: categoryName;
// Use hashcode to consistently select a color for this category
var colorIndex = Math.Abs(categoryName.GetHashCode()) % CategoryColors.Length;
_categoryColor = CategoryColors[colorIndex];
}
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null!;
public bool IsEnabled(LogLevelMicrosoft logLevel)
{
// Prevent infinite loop during UnityMcpPlugin initialization by checking if any instance exists
if (!UnityMcpPlugin.HasAnyInstance)
{
// During initialization, allow all log levels
return true;
}
return UnityMcpPlugin.IsLogEnabled(logLevel switch
{
LogLevelMicrosoft.Critical => LogLevel.Exception,
LogLevelMicrosoft.Error => LogLevel.Error,
LogLevelMicrosoft.Warning => LogLevel.Warning,
LogLevelMicrosoft.Information => LogLevel.Info,
LogLevelMicrosoft.Debug => LogLevel.Debug,
LogLevelMicrosoft.Trace => LogLevel.Trace,
_ => LogLevel.None
});
}
public void Log<TState>(LogLevelMicrosoft logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel)) return;
if (formatter == null) throw new ArgumentNullException(nameof(formatter));
if (state == null) throw new ArgumentNullException(nameof(state));
// Map LogLevel to short names
#if UNITY_EDITOR
string logLevelShort = logLevel switch
{
LogLevelMicrosoft.Critical => "<color=#ff0000>crit:</color>",
LogLevelMicrosoft.Error => "<color=#ff6b6b>fail:</color>",
LogLevelMicrosoft.Warning => "<color=#ffaa00>warn:</color>",
LogLevelMicrosoft.Information => "<color=#00ff00>info:</color>",
LogLevelMicrosoft.Debug => "<color=#00ffff>dbug:</color>",
LogLevelMicrosoft.Trace => "<color=#aaaaaa>trce:</color>",
_ => "<color=#ffffff>none</color>"
};
var message = $"{logLevelShort} [{DateTime.Now:HH:mm:ss:ffff}] <color=#B4FF32>[AI]</color> <color={_categoryColor}><b>{_categoryName}</b></color> {formatter(state, exception)}";
#else
string logLevelShort = logLevel switch
{
LogLevelMicrosoft.Critical => "crit:",
LogLevelMicrosoft.Error => "fail:",
LogLevelMicrosoft.Warning => "warn:",
LogLevelMicrosoft.Information => "info:",
LogLevelMicrosoft.Debug => "dbug:",
LogLevelMicrosoft.Trace => "trce:",
_ => "none"
};
var message = $"{logLevelShort} [{DateTime.Now:HH:mm:ss:ffff}] [AI] {_categoryName} {formatter(state, exception)}";
#endif
switch (logLevel)
{
case LogLevelMicrosoft.Critical:
case LogLevelMicrosoft.Error:
if (exception != null)
UnityEngine.Debug.LogException(exception);
UnityEngine.Debug.LogError(message);
break;
case LogLevelMicrosoft.Warning:
if (exception != null)
UnityEngine.Debug.LogWarning(exception);
UnityEngine.Debug.LogWarning(message);
break;
default:
if (exception != null)
UnityEngine.Debug.Log(exception);
UnityEngine.Debug.Log(message);
break;
}
}
}
}