@atelierai/uco 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/package.json +1 -1
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetConfig.cs +132 -132
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetDependencyResolver.cs +237 -237
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/DependencyResolver/NuGetDownloader.cs +82 -82
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Resource/MenuItems.cs +247 -247
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Resource/ToolGroups.cs +153 -153
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/SystemTool/Skills.Create.SkillBody.cs +155 -155
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Console.GetLogs.cs +95 -95
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Docs.HttpFetcher.cs +139 -139
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Instance.ListAll.cs +72 -72
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/PathReadHelper.cs +106 -106
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Script.Validate.cs +252 -252
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Tests/TestResultCollector.cs +537 -537
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/API/Tool/Tests.cs +400 -400
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Branding/ProductInfo.cs +62 -62
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/CopilotServerManager.cs +1034 -1034
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Skills/Skill_InitialSetup.cs +197 -197
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Startup.Editor.cs +201 -201
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Startup.cs +67 -67
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/CopilotListWindowBase.cs +393 -393
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/CopilotWindowBase.cs +113 -113
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.Connection.cs +3 -3
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CopilotFeatures.cs +195 -195
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CopilotServer.cs +20 -20
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.CreateGUI.cs +354 -354
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowEditor.cs +78 -78
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/MainWindowInitializer.cs +47 -47
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UI/Window/SerializationCheckWindow.cs +190 -190
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Build.cs +91 -91
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Config.cs +298 -298
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.Static.cs +296 -296
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/UnityCopilotPluginEditor.cs +69 -69
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/PackageUtils.cs +168 -168
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/PrefsKeyMigration.cs +119 -119
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/SafeDefaultsGuard.cs +180 -180
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ScriptUtils.cs +229 -229
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/ToolsManifestGenerator.cs +200 -200
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityAuthoringAdapters.cs +1467 -1467
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityAuthoringSafetyReloadGuard.cs +65 -65
- package/vendor/plugin/com.atelierai.unity.copilot/Editor/Scripts/Utils/UnityCopilotUpdateProjectSettings.cs +66 -66
- package/vendor/plugin/com.atelierai.unity.copilot/Plugins/ReflectorNet.dll +0 -0
- package/vendor/plugin/com.atelierai.unity.copilot/Plugins/Uco.Framework.Common.dll +0 -0
- package/vendor/plugin/com.atelierai.unity.copilot/Plugins/Uco.Framework.dll +0 -0
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Converter/Json/Structures/EntityIdConverter.cs +120 -120
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Data/GameObjectMetadata.cs +110 -110
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Data/GameObjectMetadata.pre-Unity.6.5.cs +110 -110
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Unity/Logs/FileLogStorage.cs +547 -547
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.Build.cs +243 -243
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.Config.cs +3 -3
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPlugin.cs +295 -295
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginBuilder.cs +105 -105
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginRuntime.Static.cs +155 -155
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/UnityCopilotPluginRuntime.cs +59 -59
- package/vendor/plugin/com.atelierai.unity.copilot/Runtime/Utils/EnvironmentUtils.cs +11 -11
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AtomicApi/AtomicApiTestFixtures.cs +99 -99
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AtomicApi/TryModifyAtTests.cs +227 -227
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/AuthoringSafetyPilotTests.cs +1050 -1050
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/DependencyResolver/NuGetLegacyMigrationTests.cs +304 -304
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Environment/EnvironmentUtilsTests.cs +1 -1
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/BlacklistTypeTests.cs +416 -416
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataFieldScriptableObjectPopulationTests.cs +172 -172
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataFieldScriptableObjectPopulationTests.pre-Unity.6.5.cs +169 -169
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPopulationTests.cs +182 -182
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPopulationTests.pre-Unity.6.5.cs +179 -179
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyPopulationTests.cs +175 -175
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyPopulationTests.pre-Unity.6.5.cs +174 -174
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyScriptableObjectPopulationTests.cs +171 -171
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ReflectionConverter/DataPropertyScriptableObjectPopulationTests.pre-Unity.6.5.cs +170 -170
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsCreateFolderTests.cs +243 -243
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsMaterialTests.cs +101 -101
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsPrefabCreateTests.cs +348 -348
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsPrefabCreateTests.pre-Unity.6.5.cs +348 -348
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Assets/AssetsShaderTests.cs +194 -194
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/PathBasedToolTests.cs +573 -573
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/PathBasedToolTests.pre-Unity.6.5.cs +513 -513
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotCameraTests.cs +154 -154
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotCameraTests.pre-Unity.6.5.cs +154 -154
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotGameViewTests.cs +164 -164
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/Screenshot/ScreenshotSceneViewTests.cs +155 -155
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolParameterTests.cs +56 -56
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolThreadSafetyTests.cs +651 -651
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/Tool/ToolThreadSafetyTests.pre-Unity.6.5.cs +651 -651
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/ToolBatchExecutionIntegrationTests.cs +407 -407
- package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/{McpPluginTests.cs → UcoPluginTests.cs} +105 -105
- package/vendor/plugin/com.atelierai.unity.copilot/package.json +1 -1
- /package/vendor/plugin/com.atelierai.unity.copilot/Tests/Editor/{McpPluginTests.cs.meta → UcoPluginTests.cs.meta} +0 -0
|
@@ -1,201 +1,201 @@
|
|
|
1
|
-
/*
|
|
2
|
-
┌──────────────────────────────────────────────────────────────────┐
|
|
3
|
-
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
|
|
4
|
-
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
|
|
5
|
-
│ Copyright (c) 2025 Ivan Murzak │
|
|
6
|
-
│ Licensed under the Apache License, Version 2.0. │
|
|
7
|
-
│ See the LICENSE file in the project root for more information. │
|
|
8
|
-
└──────────────────────────────────────────────────────────────────┘
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
#nullable enable
|
|
12
|
-
using com.AtelierAI.Unity.Copilot.Runtime.Utils;
|
|
13
|
-
using com.AtelierAI.Unity.Copilot.Editor.Utils;
|
|
14
|
-
using com.AtelierAI.Uco.Framework;
|
|
15
|
-
using Microsoft.Extensions.Logging;
|
|
16
|
-
using UnityEditor;
|
|
17
|
-
using UnityEngine;
|
|
18
|
-
|
|
19
|
-
namespace com.AtelierAI.Unity.Copilot.Editor
|
|
20
|
-
{
|
|
21
|
-
public static partial class Startup
|
|
22
|
-
{
|
|
23
|
-
static void SubscribeOnEditorEvents()
|
|
24
|
-
{
|
|
25
|
-
Application.unloading += OnApplicationUnloading;
|
|
26
|
-
Application.quitting += OnApplicationQuitting;
|
|
27
|
-
|
|
28
|
-
AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
|
|
29
|
-
AssemblyReloadEvents.afterAssemblyReload += OnAfterAssemblyReload;
|
|
30
|
-
|
|
31
|
-
// Handle Play mode state changes to ensure reconnection after exiting Play mode
|
|
32
|
-
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
|
33
|
-
}
|
|
34
|
-
static void OnApplicationUnloading() => TryDisconnectAndCleanup(nameof(OnApplicationUnloading));
|
|
35
|
-
static void OnApplicationQuitting() => TryDisconnectAndCleanup(nameof(OnApplicationQuitting));
|
|
36
|
-
static void OnBeforeAssemblyReload()
|
|
37
|
-
{
|
|
38
|
-
EditorToolExecutionScheduler.Shared.InvalidateInstance();
|
|
39
|
-
EditorOperationOwnerRegistry.InvalidateGeneration();
|
|
40
|
-
UnityAuthoringSafetyReloadGuard.InvalidateConfirmationPlans();
|
|
41
|
-
TryDisconnectAndCleanup(nameof(OnBeforeAssemblyReload));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/// <summary>
|
|
45
|
-
/// Safely disconnects and cleans up the
|
|
46
|
-
/// Catches exceptions to prevent blocking Unity's shutdown/reload process.
|
|
47
|
-
/// </summary>
|
|
48
|
-
/// <param name="callerName">Name of the calling method for logging.</param>
|
|
49
|
-
/// <param name="onlyIfConnected">If true, only disconnects when in Connected state.
|
|
50
|
-
/// This prevents issues when cancelling in-progress connection attempts during assembly reload.
|
|
51
|
-
/// Note: Log collector disposal always occurs regardless of this flag.</param>
|
|
52
|
-
static void TryDisconnectAndCleanup(string callerName, bool onlyIfConnected = false)
|
|
53
|
-
{
|
|
54
|
-
if (!UnityCopilotPluginEditor.HasInstance)
|
|
55
|
-
{
|
|
56
|
-
_logger.LogDebug("{class} {method} triggered: No UnityCopilotPluginEditor instance to disconnect",
|
|
57
|
-
nameof(Startup), callerName);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
_logger.LogInformation("{method} triggered", callerName);
|
|
62
|
-
|
|
63
|
-
var plugin = UnityCopilotPluginEditor.Instance;
|
|
64
|
-
if (plugin.
|
|
65
|
-
{
|
|
66
|
-
var connectionState = UnityCopilotPluginEditor.ConnectionState.CurrentValue;
|
|
67
|
-
|
|
68
|
-
// When onlyIfConnected is true, skip disconnect unless we have an established connection.
|
|
69
|
-
// This prevents hanging when cancelling in-progress connection attempts (Connecting/Reconnecting states).
|
|
70
|
-
if (onlyIfConnected && connectionState != ConnectionState.Connected)
|
|
71
|
-
{
|
|
72
|
-
_logger.LogTrace("Skipping {method} - not connected (state: {state})",
|
|
73
|
-
nameof(plugin.DisconnectImmediate), connectionState);
|
|
74
|
-
}
|
|
75
|
-
else
|
|
76
|
-
{
|
|
77
|
-
try
|
|
78
|
-
{
|
|
79
|
-
plugin.DisconnectImmediate();
|
|
80
|
-
}
|
|
81
|
-
catch (System.Exception e)
|
|
82
|
-
{
|
|
83
|
-
_logger.LogWarning(e, "{class} {method}: Exception during disconnect (non-blocking): {message}",
|
|
84
|
-
nameof(Startup), callerName, e.Message);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
try
|
|
90
|
-
{
|
|
91
|
-
plugin.DisposeLogCollector();
|
|
92
|
-
}
|
|
93
|
-
catch (System.Exception e)
|
|
94
|
-
{
|
|
95
|
-
_logger.LogWarning(e, "{class} {method}: Exception during log collector disposal (non-blocking): {message}",
|
|
96
|
-
nameof(Startup), callerName, e.Message);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (UnityCopilotPluginRuntime.HasInstance)
|
|
100
|
-
{
|
|
101
|
-
try
|
|
102
|
-
{
|
|
103
|
-
UnityCopilotPluginRuntime.DisposeInstance();
|
|
104
|
-
}
|
|
105
|
-
catch (System.Exception e)
|
|
106
|
-
{
|
|
107
|
-
_logger.LogWarning(e, "{class} {method}: Exception during runtime plugin disposal (non-blocking): {message}",
|
|
108
|
-
nameof(Startup), callerName, e.Message);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
static void OnAfterAssemblyReload()
|
|
113
|
-
{
|
|
114
|
-
var isCi = EnvironmentUtils.IsCi();
|
|
115
|
-
var isBatchMode = EnvironmentUtils.IsBatchMode();
|
|
116
|
-
var keepConnected = UnityCopilotPluginEditor.KeepConnected;
|
|
117
|
-
// COCli-13: batchmode launches (offline builds, command-line
|
|
118
|
-
// automation) skip the connection retry loop unless the
|
|
119
|
-
// configuration explicitly keeps the server running — connection
|
|
120
|
-
// warnings would otherwise pollute BuildReport output.
|
|
121
|
-
var connectionAllowed = keepConnected || (!isCi && !isBatchMode);
|
|
122
|
-
|
|
123
|
-
_logger.LogInformation("{method} triggered - BuildAndStart with connectionAllowed: {connectionAllowed} (isCi: {isCi}, isBatchMode: {isBatchMode}, keepConnected: {keepConnected})",
|
|
124
|
-
nameof(OnAfterAssemblyReload), connectionAllowed, isCi, isBatchMode, keepConnected);
|
|
125
|
-
|
|
126
|
-
UnityCopilotPluginEditor.Instance.
|
|
127
|
-
UnityCopilotPluginEditor.Instance.AddUnityLogCollectorIfNeeded(() => new BufferedFileLogStorage());
|
|
128
|
-
|
|
129
|
-
if (connectionAllowed)
|
|
130
|
-
UnityCopilotPluginEditor.ConnectIfNeeded();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
static void OnPlayModeStateChanged(PlayModeStateChange state)
|
|
134
|
-
{
|
|
135
|
-
if (!UnityCopilotPluginEditor.HasInstance)
|
|
136
|
-
{
|
|
137
|
-
_logger.LogDebug("{class} {method} triggered: No UnityCopilotPluginEditor instance available. State: {state}",
|
|
138
|
-
nameof(Startup), nameof(OnPlayModeStateChanged), state);
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Log Play mode state changes for debugging
|
|
143
|
-
_logger.LogInformation("Play mode state changed: {state}", state);
|
|
144
|
-
|
|
145
|
-
switch (state)
|
|
146
|
-
{
|
|
147
|
-
case PlayModeStateChange.ExitingPlayMode:
|
|
148
|
-
// Dispose the runtime plugin instance created by Initialize().Build().
|
|
149
|
-
// This handles the no-domain-reload case; TryDisconnectAndCleanup covers the domain-reload case.
|
|
150
|
-
_logger.LogTrace("Exiting Play mode - disposing runtime plugin instance if present");
|
|
151
|
-
if (UnityCopilotPluginRuntime.HasInstance)
|
|
152
|
-
UnityCopilotPluginRuntime.DisposeInstance();
|
|
153
|
-
break;
|
|
154
|
-
|
|
155
|
-
case PlayModeStateChange.EnteredEditMode:
|
|
156
|
-
// Unity has returned to Edit mode - ensure connection is re-established
|
|
157
|
-
// if the configuration expects it to be connected
|
|
158
|
-
var isCi = EnvironmentUtils.IsCi();
|
|
159
|
-
var isBatchMode = EnvironmentUtils.IsBatchMode();
|
|
160
|
-
var keepConnected = UnityCopilotPluginEditor.KeepConnected;
|
|
161
|
-
_logger.LogTrace("Entered Edit mode - KeepConnected: {keepConnected}, IsCi: {isCi}, IsBatchMode: {isBatchMode}",
|
|
162
|
-
keepConnected, isCi, isBatchMode);
|
|
163
|
-
|
|
164
|
-
if ((isCi || isBatchMode) && !keepConnected)
|
|
165
|
-
{
|
|
166
|
-
_logger.LogTrace("Skipping reconnection in CI/batchmode environment (KeepConnected is false)");
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
_logger.LogTrace("Scheduling reconnection after Play mode exit");
|
|
171
|
-
|
|
172
|
-
// Small delay to ensure Unity is fully settled in Edit mode
|
|
173
|
-
EditorApplication.delayCall += () =>
|
|
174
|
-
{
|
|
175
|
-
_logger.LogTrace("Initiating delayed reconnection after Play mode exit");
|
|
176
|
-
|
|
177
|
-
UnityCopilotPluginEditor.Instance.
|
|
178
|
-
UnityCopilotPluginEditor.Instance.AddUnityLogCollectorIfNeeded(() => new BufferedFileLogStorage());
|
|
179
|
-
UnityCopilotPluginEditor.ConnectIfNeeded();
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
// No delay, immediate reconnection for the case if Unity Editor in background
|
|
183
|
-
// (has no focus)
|
|
184
|
-
_logger.LogTrace("Initiating reconnection after Play mode exit");
|
|
185
|
-
|
|
186
|
-
UnityCopilotPluginEditor.Instance.
|
|
187
|
-
UnityCopilotPluginEditor.Instance.AddUnityLogCollectorIfNeeded(() => new BufferedFileLogStorage());
|
|
188
|
-
UnityCopilotPluginEditor.ConnectIfNeeded();
|
|
189
|
-
break;
|
|
190
|
-
|
|
191
|
-
case PlayModeStateChange.ExitingEditMode:
|
|
192
|
-
_logger.LogTrace("Exiting Edit mode to enter Play mode");
|
|
193
|
-
break;
|
|
194
|
-
|
|
195
|
-
case PlayModeStateChange.EnteredPlayMode:
|
|
196
|
-
_logger.LogTrace("Entered Play mode");
|
|
197
|
-
break;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
3
|
+
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
|
|
4
|
+
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
|
|
5
|
+
│ Copyright (c) 2025 Ivan Murzak │
|
|
6
|
+
│ Licensed under the Apache License, Version 2.0. │
|
|
7
|
+
│ See the LICENSE file in the project root for more information. │
|
|
8
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#nullable enable
|
|
12
|
+
using com.AtelierAI.Unity.Copilot.Runtime.Utils;
|
|
13
|
+
using com.AtelierAI.Unity.Copilot.Editor.Utils;
|
|
14
|
+
using com.AtelierAI.Uco.Framework;
|
|
15
|
+
using Microsoft.Extensions.Logging;
|
|
16
|
+
using UnityEditor;
|
|
17
|
+
using UnityEngine;
|
|
18
|
+
|
|
19
|
+
namespace com.AtelierAI.Unity.Copilot.Editor
|
|
20
|
+
{
|
|
21
|
+
public static partial class Startup
|
|
22
|
+
{
|
|
23
|
+
static void SubscribeOnEditorEvents()
|
|
24
|
+
{
|
|
25
|
+
Application.unloading += OnApplicationUnloading;
|
|
26
|
+
Application.quitting += OnApplicationQuitting;
|
|
27
|
+
|
|
28
|
+
AssemblyReloadEvents.beforeAssemblyReload += OnBeforeAssemblyReload;
|
|
29
|
+
AssemblyReloadEvents.afterAssemblyReload += OnAfterAssemblyReload;
|
|
30
|
+
|
|
31
|
+
// Handle Play mode state changes to ensure reconnection after exiting Play mode
|
|
32
|
+
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
|
33
|
+
}
|
|
34
|
+
static void OnApplicationUnloading() => TryDisconnectAndCleanup(nameof(OnApplicationUnloading));
|
|
35
|
+
static void OnApplicationQuitting() => TryDisconnectAndCleanup(nameof(OnApplicationQuitting));
|
|
36
|
+
static void OnBeforeAssemblyReload()
|
|
37
|
+
{
|
|
38
|
+
EditorToolExecutionScheduler.Shared.InvalidateInstance();
|
|
39
|
+
EditorOperationOwnerRegistry.InvalidateGeneration();
|
|
40
|
+
UnityAuthoringSafetyReloadGuard.InvalidateConfirmationPlans();
|
|
41
|
+
TryDisconnectAndCleanup(nameof(OnBeforeAssemblyReload));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// <summary>
|
|
45
|
+
/// Safely disconnects and cleans up the Uco plugin instance.
|
|
46
|
+
/// Catches exceptions to prevent blocking Unity's shutdown/reload process.
|
|
47
|
+
/// </summary>
|
|
48
|
+
/// <param name="callerName">Name of the calling method for logging.</param>
|
|
49
|
+
/// <param name="onlyIfConnected">If true, only disconnects when in Connected state.
|
|
50
|
+
/// This prevents issues when cancelling in-progress connection attempts during assembly reload.
|
|
51
|
+
/// Note: Log collector disposal always occurs regardless of this flag.</param>
|
|
52
|
+
static void TryDisconnectAndCleanup(string callerName, bool onlyIfConnected = false)
|
|
53
|
+
{
|
|
54
|
+
if (!UnityCopilotPluginEditor.HasInstance)
|
|
55
|
+
{
|
|
56
|
+
_logger.LogDebug("{class} {method} triggered: No UnityCopilotPluginEditor instance to disconnect",
|
|
57
|
+
nameof(Startup), callerName);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
_logger.LogInformation("{method} triggered", callerName);
|
|
62
|
+
|
|
63
|
+
var plugin = UnityCopilotPluginEditor.Instance;
|
|
64
|
+
if (plugin.HasUcoPluginInstance)
|
|
65
|
+
{
|
|
66
|
+
var connectionState = UnityCopilotPluginEditor.ConnectionState.CurrentValue;
|
|
67
|
+
|
|
68
|
+
// When onlyIfConnected is true, skip disconnect unless we have an established connection.
|
|
69
|
+
// This prevents hanging when cancelling in-progress connection attempts (Connecting/Reconnecting states).
|
|
70
|
+
if (onlyIfConnected && connectionState != ConnectionState.Connected)
|
|
71
|
+
{
|
|
72
|
+
_logger.LogTrace("Skipping {method} - not connected (state: {state})",
|
|
73
|
+
nameof(plugin.DisconnectImmediate), connectionState);
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
{
|
|
77
|
+
try
|
|
78
|
+
{
|
|
79
|
+
plugin.DisconnectImmediate();
|
|
80
|
+
}
|
|
81
|
+
catch (System.Exception e)
|
|
82
|
+
{
|
|
83
|
+
_logger.LogWarning(e, "{class} {method}: Exception during disconnect (non-blocking): {message}",
|
|
84
|
+
nameof(Startup), callerName, e.Message);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try
|
|
90
|
+
{
|
|
91
|
+
plugin.DisposeLogCollector();
|
|
92
|
+
}
|
|
93
|
+
catch (System.Exception e)
|
|
94
|
+
{
|
|
95
|
+
_logger.LogWarning(e, "{class} {method}: Exception during log collector disposal (non-blocking): {message}",
|
|
96
|
+
nameof(Startup), callerName, e.Message);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (UnityCopilotPluginRuntime.HasInstance)
|
|
100
|
+
{
|
|
101
|
+
try
|
|
102
|
+
{
|
|
103
|
+
UnityCopilotPluginRuntime.DisposeInstance();
|
|
104
|
+
}
|
|
105
|
+
catch (System.Exception e)
|
|
106
|
+
{
|
|
107
|
+
_logger.LogWarning(e, "{class} {method}: Exception during runtime plugin disposal (non-blocking): {message}",
|
|
108
|
+
nameof(Startup), callerName, e.Message);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
static void OnAfterAssemblyReload()
|
|
113
|
+
{
|
|
114
|
+
var isCi = EnvironmentUtils.IsCi();
|
|
115
|
+
var isBatchMode = EnvironmentUtils.IsBatchMode();
|
|
116
|
+
var keepConnected = UnityCopilotPluginEditor.KeepConnected;
|
|
117
|
+
// COCli-13: batchmode launches (offline builds, command-line
|
|
118
|
+
// automation) skip the connection retry loop unless the
|
|
119
|
+
// configuration explicitly keeps the server running — connection
|
|
120
|
+
// warnings would otherwise pollute BuildReport output.
|
|
121
|
+
var connectionAllowed = keepConnected || (!isCi && !isBatchMode);
|
|
122
|
+
|
|
123
|
+
_logger.LogInformation("{method} triggered - BuildAndStart with connectionAllowed: {connectionAllowed} (isCi: {isCi}, isBatchMode: {isBatchMode}, keepConnected: {keepConnected})",
|
|
124
|
+
nameof(OnAfterAssemblyReload), connectionAllowed, isCi, isBatchMode, keepConnected);
|
|
125
|
+
|
|
126
|
+
UnityCopilotPluginEditor.Instance.BuildUcoPluginIfNeeded();
|
|
127
|
+
UnityCopilotPluginEditor.Instance.AddUnityLogCollectorIfNeeded(() => new BufferedFileLogStorage());
|
|
128
|
+
|
|
129
|
+
if (connectionAllowed)
|
|
130
|
+
UnityCopilotPluginEditor.ConnectIfNeeded();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static void OnPlayModeStateChanged(PlayModeStateChange state)
|
|
134
|
+
{
|
|
135
|
+
if (!UnityCopilotPluginEditor.HasInstance)
|
|
136
|
+
{
|
|
137
|
+
_logger.LogDebug("{class} {method} triggered: No UnityCopilotPluginEditor instance available. State: {state}",
|
|
138
|
+
nameof(Startup), nameof(OnPlayModeStateChanged), state);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Log Play mode state changes for debugging
|
|
143
|
+
_logger.LogInformation("Play mode state changed: {state}", state);
|
|
144
|
+
|
|
145
|
+
switch (state)
|
|
146
|
+
{
|
|
147
|
+
case PlayModeStateChange.ExitingPlayMode:
|
|
148
|
+
// Dispose the runtime plugin instance created by Initialize().Build().
|
|
149
|
+
// This handles the no-domain-reload case; TryDisconnectAndCleanup covers the domain-reload case.
|
|
150
|
+
_logger.LogTrace("Exiting Play mode - disposing runtime plugin instance if present");
|
|
151
|
+
if (UnityCopilotPluginRuntime.HasInstance)
|
|
152
|
+
UnityCopilotPluginRuntime.DisposeInstance();
|
|
153
|
+
break;
|
|
154
|
+
|
|
155
|
+
case PlayModeStateChange.EnteredEditMode:
|
|
156
|
+
// Unity has returned to Edit mode - ensure connection is re-established
|
|
157
|
+
// if the configuration expects it to be connected
|
|
158
|
+
var isCi = EnvironmentUtils.IsCi();
|
|
159
|
+
var isBatchMode = EnvironmentUtils.IsBatchMode();
|
|
160
|
+
var keepConnected = UnityCopilotPluginEditor.KeepConnected;
|
|
161
|
+
_logger.LogTrace("Entered Edit mode - KeepConnected: {keepConnected}, IsCi: {isCi}, IsBatchMode: {isBatchMode}",
|
|
162
|
+
keepConnected, isCi, isBatchMode);
|
|
163
|
+
|
|
164
|
+
if ((isCi || isBatchMode) && !keepConnected)
|
|
165
|
+
{
|
|
166
|
+
_logger.LogTrace("Skipping reconnection in CI/batchmode environment (KeepConnected is false)");
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
_logger.LogTrace("Scheduling reconnection after Play mode exit");
|
|
171
|
+
|
|
172
|
+
// Small delay to ensure Unity is fully settled in Edit mode
|
|
173
|
+
EditorApplication.delayCall += () =>
|
|
174
|
+
{
|
|
175
|
+
_logger.LogTrace("Initiating delayed reconnection after Play mode exit");
|
|
176
|
+
|
|
177
|
+
UnityCopilotPluginEditor.Instance.BuildUcoPluginIfNeeded();
|
|
178
|
+
UnityCopilotPluginEditor.Instance.AddUnityLogCollectorIfNeeded(() => new BufferedFileLogStorage());
|
|
179
|
+
UnityCopilotPluginEditor.ConnectIfNeeded();
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// No delay, immediate reconnection for the case if Unity Editor in background
|
|
183
|
+
// (has no focus)
|
|
184
|
+
_logger.LogTrace("Initiating reconnection after Play mode exit");
|
|
185
|
+
|
|
186
|
+
UnityCopilotPluginEditor.Instance.BuildUcoPluginIfNeeded();
|
|
187
|
+
UnityCopilotPluginEditor.Instance.AddUnityLogCollectorIfNeeded(() => new BufferedFileLogStorage());
|
|
188
|
+
UnityCopilotPluginEditor.ConnectIfNeeded();
|
|
189
|
+
break;
|
|
190
|
+
|
|
191
|
+
case PlayModeStateChange.ExitingEditMode:
|
|
192
|
+
_logger.LogTrace("Exiting Edit mode to enter Play mode");
|
|
193
|
+
break;
|
|
194
|
+
|
|
195
|
+
case PlayModeStateChange.EnteredPlayMode:
|
|
196
|
+
_logger.LogTrace("Entered Play mode");
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
/*
|
|
2
|
-
┌──────────────────────────────────────────────────────────────────┐
|
|
3
|
-
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
|
|
4
|
-
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
|
|
5
|
-
│ Copyright (c) 2025 Ivan Murzak │
|
|
6
|
-
│ Licensed under the Apache License, Version 2.0. │
|
|
7
|
-
│ See the LICENSE file in the project root for more information. │
|
|
8
|
-
└──────────────────────────────────────────────────────────────────┘
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
#nullable enable
|
|
12
|
-
using com.AtelierAI.Unity.Copilot.Editor.UI;
|
|
13
|
-
using com.AtelierAI.Unity.Copilot.Editor.Utils;
|
|
14
|
-
using com.AtelierAI.Unity.Copilot.Utils;
|
|
15
|
-
using Microsoft.Extensions.Logging;
|
|
16
|
-
using UnityEditor;
|
|
17
|
-
using UnityEngine;
|
|
18
|
-
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
|
19
|
-
|
|
20
|
-
namespace com.AtelierAI.Unity.Copilot.Editor
|
|
21
|
-
{
|
|
22
|
-
[InitializeOnLoad]
|
|
23
|
-
public static partial class Startup
|
|
24
|
-
{
|
|
25
|
-
static readonly ILogger _logger = UnityLoggerFactory.LoggerFactory.CreateLogger(nameof(Startup));
|
|
26
|
-
|
|
27
|
-
static Startup()
|
|
28
|
-
{
|
|
29
|
-
if (!UnityProcessGuard.ShouldInitialize(AssetDatabase.IsAssetImportWorkerProcess()))
|
|
30
|
-
{
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
EditorOperationOwners.RegisterAndReconcile();
|
|
35
|
-
UnityCopilotPluginEditor.Instance.
|
|
36
|
-
UnityCopilotPluginEditor.Instance.AddUnityLogCollectorIfNeeded(() => new BufferedFileLogStorage());
|
|
37
|
-
|
|
38
|
-
// Informational notice — historically the plugin treated a space in the project
|
|
39
|
-
// path as a hard error, but in practice the modern startup pipeline (structured
|
|
40
|
-
// ProcessStartInfo, JSON/TOML client configs with quoted command strings,
|
|
41
|
-
// Path.Combine-based file IO) handles spaces correctly. We keep a one-shot
|
|
42
|
-
// warning so users have a breadcrumb if they hit a third-party tool that does
|
|
43
|
-
// not tolerate spaces in paths.
|
|
44
|
-
if (Application.dataPath.Contains(" "))
|
|
45
|
-
Debug.LogWarning("Unity Copilot: project path contains spaces. The plugin will start normally; if any specific workflow misbehaves with this path, please report it so we can fix the underlying issue.");
|
|
46
|
-
|
|
47
|
-
SubscribeOnEditorEvents();
|
|
48
|
-
|
|
49
|
-
// Initialize sub-systems
|
|
50
|
-
API.Tool_Tests.Init();
|
|
51
|
-
UpdateChecker.Init();
|
|
52
|
-
PackageUtils.Init();
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/// <summary>
|
|
57
|
-
/// Asset Import Workers inherit the main Editor's environment variables but
|
|
58
|
-
/// must never create their own
|
|
59
|
-
/// advertises the same project instance ID, cannot complete normal Editor
|
|
60
|
-
/// registration, and can otherwise displace the main Editor connection.
|
|
61
|
-
/// </summary>
|
|
62
|
-
internal static class UnityProcessGuard
|
|
63
|
-
{
|
|
64
|
-
internal static bool ShouldInitialize(bool isAssetImportWorkerProcess)
|
|
65
|
-
=> !isAssetImportWorkerProcess;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
┌──────────────────────────────────────────────────────────────────┐
|
|
3
|
+
│ Author: Ivan Murzak (https://github.com/IvanMurzak) │
|
|
4
|
+
│ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │
|
|
5
|
+
│ Copyright (c) 2025 Ivan Murzak │
|
|
6
|
+
│ Licensed under the Apache License, Version 2.0. │
|
|
7
|
+
│ See the LICENSE file in the project root for more information. │
|
|
8
|
+
└──────────────────────────────────────────────────────────────────┘
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#nullable enable
|
|
12
|
+
using com.AtelierAI.Unity.Copilot.Editor.UI;
|
|
13
|
+
using com.AtelierAI.Unity.Copilot.Editor.Utils;
|
|
14
|
+
using com.AtelierAI.Unity.Copilot.Utils;
|
|
15
|
+
using Microsoft.Extensions.Logging;
|
|
16
|
+
using UnityEditor;
|
|
17
|
+
using UnityEngine;
|
|
18
|
+
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
|
19
|
+
|
|
20
|
+
namespace com.AtelierAI.Unity.Copilot.Editor
|
|
21
|
+
{
|
|
22
|
+
[InitializeOnLoad]
|
|
23
|
+
public static partial class Startup
|
|
24
|
+
{
|
|
25
|
+
static readonly ILogger _logger = UnityLoggerFactory.LoggerFactory.CreateLogger(nameof(Startup));
|
|
26
|
+
|
|
27
|
+
static Startup()
|
|
28
|
+
{
|
|
29
|
+
if (!UnityProcessGuard.ShouldInitialize(AssetDatabase.IsAssetImportWorkerProcess()))
|
|
30
|
+
{
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
EditorOperationOwners.RegisterAndReconcile();
|
|
35
|
+
UnityCopilotPluginEditor.Instance.BuildUcoPluginIfNeeded();
|
|
36
|
+
UnityCopilotPluginEditor.Instance.AddUnityLogCollectorIfNeeded(() => new BufferedFileLogStorage());
|
|
37
|
+
|
|
38
|
+
// Informational notice — historically the plugin treated a space in the project
|
|
39
|
+
// path as a hard error, but in practice the modern startup pipeline (structured
|
|
40
|
+
// ProcessStartInfo, JSON/TOML client configs with quoted command strings,
|
|
41
|
+
// Path.Combine-based file IO) handles spaces correctly. We keep a one-shot
|
|
42
|
+
// warning so users have a breadcrumb if they hit a third-party tool that does
|
|
43
|
+
// not tolerate spaces in paths.
|
|
44
|
+
if (Application.dataPath.Contains(" "))
|
|
45
|
+
Debug.LogWarning("Unity Copilot: project path contains spaces. The plugin will start normally; if any specific workflow misbehaves with this path, please report it so we can fix the underlying issue.");
|
|
46
|
+
|
|
47
|
+
SubscribeOnEditorEvents();
|
|
48
|
+
|
|
49
|
+
// Initialize sub-systems
|
|
50
|
+
API.Tool_Tests.Init();
|
|
51
|
+
UpdateChecker.Init();
|
|
52
|
+
PackageUtils.Init();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/// <summary>
|
|
57
|
+
/// Asset Import Workers inherit the main Editor's environment variables but
|
|
58
|
+
/// must never create their own Uco plugin/server lifecycle. A worker bridge
|
|
59
|
+
/// advertises the same project instance ID, cannot complete normal Editor
|
|
60
|
+
/// registration, and can otherwise displace the main Editor connection.
|
|
61
|
+
/// </summary>
|
|
62
|
+
internal static class UnityProcessGuard
|
|
63
|
+
{
|
|
64
|
+
internal static bool ShouldInitialize(bool isAssetImportWorkerProcess)
|
|
65
|
+
=> !isAssetImportWorkerProcess;
|
|
66
|
+
}
|
|
67
|
+
}
|