@mflrevan/ucp 0.5.1 → 0.6.0

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.
Files changed (35) hide show
  1. package/README.md +1 -1
  2. package/bridge/com.ucp.bridge/Editor/AssemblyInfo.cs +3 -0
  3. package/bridge/com.ucp.bridge/Editor/AssemblyInfo.cs.meta +2 -0
  4. package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs +16 -3
  5. package/bridge/com.ucp.bridge/Editor/Compatibility/UnityObjectCompat.cs +26 -0
  6. package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs +172 -2
  7. package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs +88 -1
  8. package/bridge/com.ucp.bridge/Editor/Controllers/EditorModalGuard.cs +60 -0
  9. package/bridge/com.ucp.bridge/Editor/Controllers/EditorModalGuard.cs.meta +2 -0
  10. package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs +56 -5
  11. package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs +325 -13
  12. package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs +2 -2
  13. package/bridge/com.ucp.bridge/Editor/Controllers/ObjectLocator.cs +207 -0
  14. package/bridge/com.ucp.bridge/Editor/Controllers/ObjectLocator.cs.meta +2 -0
  15. package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs +1 -1
  16. package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs +14 -35
  17. package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs +3 -3
  18. package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs +1 -1
  19. package/bridge/com.ucp.bridge/Editor/Controllers/ReferenceController.cs +1 -1
  20. package/bridge/com.ucp.bridge/Editor/Controllers/SceneChangeTracker.cs +6 -6
  21. package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs +2 -34
  22. package/bridge/com.ucp.bridge/Editor/Controllers/ShaderController.cs +151 -0
  23. package/bridge/com.ucp.bridge/Editor/Controllers/ShaderController.cs.meta +2 -0
  24. package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs +304 -9
  25. package/bridge/com.ucp.bridge/Editor/Controllers/SpatialController.cs +322 -0
  26. package/bridge/com.ucp.bridge/Editor/Controllers/SpatialController.cs.meta +2 -0
  27. package/bridge/com.ucp.bridge/Editor/Controllers/TransformController.cs +249 -0
  28. package/bridge/com.ucp.bridge/Editor/Controllers/TransformController.cs.meta +2 -0
  29. package/bridge/com.ucp.bridge/Editor/Controllers/ViewController.cs +415 -0
  30. package/bridge/com.ucp.bridge/Editor/Controllers/ViewController.cs.meta +2 -0
  31. package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs +135 -7
  32. package/bridge/com.ucp.bridge/Tests/Editor/SpatialVisualControllerTests.cs +252 -0
  33. package/bridge/com.ucp.bridge/Tests/Editor/SpatialVisualControllerTests.cs.meta +2 -0
  34. package/bridge/com.ucp.bridge/package.json +1 -1
  35. package/package.json +1 -1
@@ -1,6 +1,4 @@
1
1
  using UnityEditor;
2
- using UnityEditor.SceneManagement;
3
- using UnityEngine.SceneManagement;
4
2
  using System.Collections.Generic;
5
3
  using System;
6
4
 
@@ -64,7 +62,10 @@ namespace UCP.Bridge
64
62
 
65
63
  var saveDirtyScenes = GetBoolParam(paramsJson, "saveDirtyScenes", true);
66
64
  var discardUntitled = GetBoolParam(paramsJson, "discardUntitled", true);
67
- SaveDirtyScenesIfRequested(saveDirtyScenes, discardUntitled);
65
+ var logFile = GetStringParam(paramsJson, "logFile");
66
+ EditorModalGuard.SaveOpenDirtyScenes(saveDirtyScenes, discardUntitled);
67
+ if (!string.IsNullOrEmpty(logFile))
68
+ LogsController.StartFileCapture(logFile);
68
69
 
69
70
  lock (s_sessionLock)
70
71
  {
@@ -88,38 +89,6 @@ namespace UCP.Bridge
88
89
  return defaultValue;
89
90
  }
90
91
 
91
- private static void SaveDirtyScenesIfRequested(bool saveDirtyScenes, bool discardUntitled)
92
- {
93
- if (!saveDirtyScenes)
94
- return;
95
-
96
- var requiresUntitledDiscard = false;
97
-
98
- for (var index = 0; index < SceneManager.sceneCount; index++)
99
- {
100
- var scene = SceneManager.GetSceneAt(index);
101
- if (!scene.isLoaded || !scene.isDirty)
102
- continue;
103
-
104
- if (string.IsNullOrEmpty(scene.path))
105
- {
106
- if (!discardUntitled)
107
- throw new System.InvalidOperationException("Dirty untitled scene cannot be auto-saved. Retry with discardUntitled=true.");
108
-
109
- requiresUntitledDiscard = true;
110
- continue;
111
- }
112
-
113
- if (!EditorSceneManager.SaveScene(scene))
114
- throw new System.InvalidOperationException($"Failed to auto-save dirty scene: {scene.path}");
115
-
116
- SceneChangeTracker.ClearScene(scene);
117
- }
118
-
119
- if (requiresUntitledDiscard)
120
- EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
121
- }
122
-
123
92
  private static object HandleStop(string paramsJson)
124
93
  {
125
94
  if (!EditorApplication.isPlaying)
@@ -151,11 +120,21 @@ namespace UCP.Bridge
151
120
  break;
152
121
  case PlayModeStateChange.EnteredEditMode:
153
122
  s_lastExitedPlayAtUtc = DateTime.UtcNow;
123
+ LogsController.StopFileCapture();
154
124
  break;
155
125
  }
156
126
  }
157
127
  }
158
128
 
129
+ private static string GetStringParam(string paramsJson, string key)
130
+ {
131
+ var parameters = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
132
+ if (parameters != null && parameters.TryGetValue(key, out var valueObj) && valueObj != null)
133
+ return valueObj.ToString();
134
+
135
+ return null;
136
+ }
137
+
159
138
  private static object SerializeSessionSnapshot(SessionSnapshot snapshot)
160
139
  {
161
140
  var now = DateTime.UtcNow;
@@ -179,8 +179,8 @@ namespace UCP.Bridge
179
179
  ["status"] = "ok",
180
180
  ["path"] = savePath,
181
181
  ["name"] = prefab.name,
182
- ["instanceId"] = prefab.GetInstanceID(),
183
- ["sceneInstanceId"] = go.GetInstanceID(),
182
+ ["instanceId"] = prefab.GetId(),
183
+ ["sceneInstanceId"] = go.GetId(),
184
184
  ["isPrefabInstance"] = PrefabUtility.IsPartOfPrefabInstance(go)
185
185
  };
186
186
  }
@@ -221,7 +221,7 @@ namespace UCP.Bridge
221
221
  added.Add(new Dictionary<string, object>
222
222
  {
223
223
  ["component"] = ac.instanceComponent.GetType().Name,
224
- ["instanceId"] = ac.instanceComponent.GetInstanceID()
224
+ ["instanceId"] = ac.instanceComponent.GetId()
225
225
  });
226
226
  }
227
227
 
@@ -538,7 +538,7 @@ namespace UCP.Bridge
538
538
 
539
539
  private static GameObject FindInHierarchy(GameObject go, int instanceId)
540
540
  {
541
- if (go.GetInstanceID() == instanceId) return go;
541
+ if (go.GetId() == instanceId) return go;
542
542
  for (int i = 0; i < go.transform.childCount; i++)
543
543
  {
544
544
  var found = FindInHierarchy(go.transform.GetChild(i).gameObject, instanceId);
@@ -31,7 +31,7 @@ namespace UCP.Bridge
31
31
  {
32
32
  { "serializationMode", mode },
33
33
  { "forceText", mode == 2 },
34
- { "visibleMetaFiles", EditorSettings.externalVersionControl == "Visible Meta Files" }
34
+ { "visibleMetaFiles", VersionControlSettings.mode == "Visible Meta Files" }
35
35
  };
36
36
  }
37
37
  finally
@@ -17,7 +17,7 @@ namespace UCP.Bridge
17
17
  public HashSet<string> Components = new();
18
18
  }
19
19
 
20
- private static readonly Dictionary<int, Dictionary<string, TrackedSceneChange>> s_changesByScene = new();
20
+ private static readonly Dictionary<long, Dictionary<string, TrackedSceneChange>> s_changesByScene = new();
21
21
 
22
22
  static SceneChangeTracker()
23
23
  {
@@ -33,7 +33,7 @@ namespace UCP.Bridge
33
33
  if (gameObject == null)
34
34
  return;
35
35
 
36
- RecordSceneChange(gameObject.scene, gameObject.GetInstanceID(), gameObject.name, componentName);
36
+ RecordSceneChange(gameObject.scene, gameObject.GetId(), gameObject.name, componentName);
37
37
  }
38
38
 
39
39
  public static void RecordDeletedObject(Scene scene, int instanceId, string name, string componentName)
@@ -56,7 +56,7 @@ namespace UCP.Bridge
56
56
  var modifications = new List<object>();
57
57
  var omittedCount = 0;
58
58
 
59
- if (scene.IsValid() && s_changesByScene.TryGetValue(scene.handle, out var trackedChanges))
59
+ if (scene.IsValid() && s_changesByScene.TryGetValue(UnityObjectCompat.GetSceneHandle(scene), out var trackedChanges))
60
60
  {
61
61
  var ordered = trackedChanges.Values
62
62
  .OrderBy(change => change.InstanceId.HasValue ? 0 : 1)
@@ -101,7 +101,7 @@ namespace UCP.Bridge
101
101
  if (!scene.IsValid())
102
102
  return;
103
103
 
104
- s_changesByScene.Remove(scene.handle);
104
+ s_changesByScene.Remove(UnityObjectCompat.GetSceneHandle(scene));
105
105
  }
106
106
 
107
107
  private static UndoPropertyModification[] OnPostprocessModifications(UndoPropertyModification[] modifications)
@@ -140,10 +140,10 @@ namespace UCP.Bridge
140
140
  if (!scene.IsValid() || !scene.isLoaded)
141
141
  return;
142
142
 
143
- if (!s_changesByScene.TryGetValue(scene.handle, out var sceneChanges))
143
+ if (!s_changesByScene.TryGetValue(UnityObjectCompat.GetSceneHandle(scene), out var sceneChanges))
144
144
  {
145
145
  sceneChanges = new Dictionary<string, TrackedSceneChange>();
146
- s_changesByScene[scene.handle] = sceneChanges;
146
+ s_changesByScene[UnityObjectCompat.GetSceneHandle(scene)] = sceneChanges;
147
147
  }
148
148
 
149
149
  var key = instanceId.HasValue ? instanceId.Value.ToString() : $"scene::{name}";
@@ -54,7 +54,7 @@ namespace UCP.Bridge
54
54
  }
55
55
  else
56
56
  {
57
- SaveDirtyScenesIfRequested(saveDirtyScenes, discardUntitled);
57
+ EditorModalGuard.SaveOpenDirtyScenes(saveDirtyScenes, discardUntitled);
58
58
  EditorSceneManager.OpenScene(path, additive ? OpenSceneMode.Additive : OpenSceneMode.Single);
59
59
  }
60
60
 
@@ -74,38 +74,6 @@ namespace UCP.Bridge
74
74
  return defaultValue;
75
75
  }
76
76
 
77
- private static void SaveDirtyScenesIfRequested(bool saveDirtyScenes, bool discardUntitled)
78
- {
79
- if (!saveDirtyScenes)
80
- return;
81
-
82
- var requiresUntitledDiscard = false;
83
-
84
- for (var index = 0; index < SceneManager.sceneCount; index++)
85
- {
86
- var scene = SceneManager.GetSceneAt(index);
87
- if (!scene.isLoaded || !scene.isDirty)
88
- continue;
89
-
90
- if (string.IsNullOrEmpty(scene.path))
91
- {
92
- if (!discardUntitled)
93
- throw new System.InvalidOperationException("Dirty untitled scene cannot be auto-saved. Retry with discardUntitled=true.");
94
-
95
- requiresUntitledDiscard = true;
96
- continue;
97
- }
98
-
99
- if (!EditorSceneManager.SaveScene(scene))
100
- throw new System.InvalidOperationException($"Failed to auto-save dirty scene: {scene.path}");
101
-
102
- SceneChangeTracker.ClearScene(scene);
103
- }
104
-
105
- if (requiresUntitledDiscard)
106
- EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
107
- }
108
-
109
77
  private static object HandleSaveActive(string paramsJson)
110
78
  {
111
79
  var scene = SceneManager.GetActiveScene();
@@ -302,7 +270,7 @@ namespace UCP.Bridge
302
270
 
303
271
  private static GameObject FindInHierarchy(GameObject gameObject, int instanceId)
304
272
  {
305
- if (gameObject.GetInstanceID() == instanceId)
273
+ if (gameObject.GetId() == instanceId)
306
274
  return gameObject;
307
275
 
308
276
  foreach (Transform child in gameObject.transform)
@@ -0,0 +1,151 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using System.Reflection;
4
+ using UnityEditor;
5
+ using UnityEngine;
6
+
7
+ namespace UCP.Bridge
8
+ {
9
+ public static class ShaderController
10
+ {
11
+ public static void Register(CommandRouter router)
12
+ {
13
+ router.Register("shader/errors", HandleErrors);
14
+ }
15
+
16
+ private static object HandleErrors(string paramsJson)
17
+ {
18
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
19
+ var errorsOnly = p != null && p.TryGetValue("errorsOnly", out var errorsOnlyObj) && errorsOnlyObj != null && Convert.ToBoolean(errorsOnlyObj);
20
+ var filter = p != null && p.TryGetValue("filter", out var filterObj) && filterObj != null ? filterObj.ToString() : null;
21
+
22
+ AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
23
+
24
+ var diagnostics = new List<object>();
25
+ var scanned = 0;
26
+ foreach (var guid in AssetDatabase.FindAssets("t:Shader"))
27
+ {
28
+ var path = AssetDatabase.GUIDToAssetPath(guid);
29
+ var shader = AssetDatabase.LoadAssetAtPath<Shader>(path);
30
+ if (shader == null)
31
+ continue;
32
+ if (!MatchesFilter(shader.name, path, filter))
33
+ continue;
34
+
35
+ scanned++;
36
+ foreach (var diagnostic in ReadShaderDiagnostics(shader, path, errorsOnly))
37
+ diagnostics.Add(diagnostic);
38
+ }
39
+
40
+ return new Dictionary<string, object>
41
+ {
42
+ ["status"] = "ok",
43
+ ["capability"] = FindShaderMessageMethod() != null ? "shader-messages" : "fallback",
44
+ ["scanned"] = scanned,
45
+ ["count"] = diagnostics.Count,
46
+ ["diagnostics"] = diagnostics
47
+ };
48
+ }
49
+
50
+ private static IEnumerable<object> ReadShaderDiagnostics(Shader shader, string path, bool errorsOnly)
51
+ {
52
+ var method = FindShaderMessageMethod();
53
+ if (method == null)
54
+ yield break;
55
+
56
+ var messages = method.Invoke(null, new object[] { shader }) as Array;
57
+ if (messages == null)
58
+ yield break;
59
+
60
+ foreach (var message in messages)
61
+ {
62
+ var isWarning = ReadBoolMember(message, "warning", "isWarning");
63
+ if (errorsOnly && isWarning)
64
+ continue;
65
+
66
+ yield return new Dictionary<string, object>
67
+ {
68
+ ["shader"] = shader.name,
69
+ ["path"] = path,
70
+ ["severity"] = isWarning ? "warning" : "error",
71
+ ["message"] = ReadStringMember(message, "message", "messageDetails"),
72
+ ["line"] = ReadIntMember(message, "line"),
73
+ ["platform"] = ReadStringMember(message, "platform"),
74
+ ["file"] = ReadStringMember(message, "file")
75
+ };
76
+ }
77
+ }
78
+
79
+ private static MethodInfo FindShaderMessageMethod()
80
+ {
81
+ var shaderUtil = typeof(Editor).Assembly.GetType("UnityEditor.ShaderUtil");
82
+ return FindShaderMethod(shaderUtil, "GetShaderMessages")
83
+ ?? FindShaderMethod(shaderUtil, "GetShaderErrors");
84
+ }
85
+
86
+ private static MethodInfo FindShaderMethod(Type shaderUtil, string name)
87
+ {
88
+ if (shaderUtil == null)
89
+ return null;
90
+
91
+ foreach (var method in shaderUtil.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
92
+ {
93
+ if (method.Name != name)
94
+ continue;
95
+ var parameters = method.GetParameters();
96
+ if (parameters.Length == 1 && parameters[0].ParameterType == typeof(Shader))
97
+ return method;
98
+ }
99
+
100
+ return null;
101
+ }
102
+
103
+ private static bool MatchesFilter(string shaderName, string path, string filter)
104
+ {
105
+ if (string.IsNullOrEmpty(filter))
106
+ return true;
107
+ return shaderName.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0
108
+ || path.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0;
109
+ }
110
+
111
+ private static string ReadStringMember(object target, params string[] names)
112
+ {
113
+ foreach (var name in names)
114
+ {
115
+ var value = ReadMember(target, name);
116
+ if (value != null)
117
+ return value.ToString();
118
+ }
119
+
120
+ return string.Empty;
121
+ }
122
+
123
+ private static int ReadIntMember(object target, string name)
124
+ {
125
+ var value = ReadMember(target, name);
126
+ return value != null ? Convert.ToInt32(value) : 0;
127
+ }
128
+
129
+ private static bool ReadBoolMember(object target, params string[] names)
130
+ {
131
+ foreach (var name in names)
132
+ {
133
+ var value = ReadMember(target, name);
134
+ if (value != null)
135
+ return Convert.ToBoolean(value);
136
+ }
137
+
138
+ return false;
139
+ }
140
+
141
+ private static object ReadMember(object target, string name)
142
+ {
143
+ var type = target.GetType();
144
+ var field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
145
+ if (field != null)
146
+ return field.GetValue(target);
147
+ var property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
148
+ return property?.GetValue(target);
149
+ }
150
+ }
151
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 4cfbd1702c2741b48996b2de530bcb96