@mflrevan/ucp 0.4.3 → 0.4.5

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 (81) hide show
  1. package/README.md +1 -1
  2. package/bridge/com.ucp.bridge/CHANGELOG.md +145 -0
  3. package/bridge/com.ucp.bridge/CHANGELOG.md.meta +7 -0
  4. package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs +583 -0
  5. package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs.meta +2 -0
  6. package/bridge/com.ucp.bridge/Editor/Bridge.meta +8 -0
  7. package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs +425 -0
  8. package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs.meta +2 -0
  9. package/bridge/com.ucp.bridge/Editor/Controllers/AssetImportSupport.cs +355 -0
  10. package/bridge/com.ucp.bridge/Editor/Controllers/AssetImportSupport.cs.meta +2 -0
  11. package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs +233 -0
  12. package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs.meta +2 -0
  13. package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs +26 -0
  14. package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs.meta +2 -0
  15. package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs +31 -0
  16. package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs.meta +2 -0
  17. package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs +527 -0
  18. package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs.meta +2 -0
  19. package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs +141 -0
  20. package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs.meta +2 -0
  21. package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs +326 -0
  22. package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs.meta +2 -0
  23. package/bridge/com.ucp.bridge/Editor/Controllers/ImporterController.cs +209 -0
  24. package/bridge/com.ucp.bridge/Editor/Controllers/ImporterController.cs.meta +2 -0
  25. package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs +409 -0
  26. package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs.meta +2 -0
  27. package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs +354 -0
  28. package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs.meta +2 -0
  29. package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs +93 -0
  30. package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs.meta +2 -0
  31. package/bridge/com.ucp.bridge/Editor/Controllers/PackagesController.cs +503 -0
  32. package/bridge/com.ucp.bridge/Editor/Controllers/PackagesController.cs.meta +2 -0
  33. package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs +188 -0
  34. package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs.meta +2 -0
  35. package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs +260 -0
  36. package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs.meta +2 -0
  37. package/bridge/com.ucp.bridge/Editor/Controllers/ProfilerController.cs +1679 -0
  38. package/bridge/com.ucp.bridge/Editor/Controllers/ProfilerController.cs.meta +2 -0
  39. package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs +563 -0
  40. package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs.meta +2 -0
  41. package/bridge/com.ucp.bridge/Editor/Controllers/SceneChangeTracker.cs +166 -0
  42. package/bridge/com.ucp.bridge/Editor/Controllers/SceneChangeTracker.cs.meta +2 -0
  43. package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs +318 -0
  44. package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs.meta +2 -0
  45. package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs +125 -0
  46. package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs.meta +2 -0
  47. package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs +104 -0
  48. package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs.meta +2 -0
  49. package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs +227 -0
  50. package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs.meta +2 -0
  51. package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs +240 -0
  52. package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs.meta +2 -0
  53. package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs +611 -0
  54. package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs.meta +2 -0
  55. package/bridge/com.ucp.bridge/Editor/Controllers.meta +8 -0
  56. package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs +53 -0
  57. package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs.meta +2 -0
  58. package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs +80 -0
  59. package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs.meta +2 -0
  60. package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs +358 -0
  61. package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs.meta +2 -0
  62. package/bridge/com.ucp.bridge/Editor/Protocol.meta +8 -0
  63. package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs +37 -0
  64. package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs.meta +2 -0
  65. package/bridge/com.ucp.bridge/Editor/Scripts.meta +8 -0
  66. package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef +16 -0
  67. package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef.meta +7 -0
  68. package/bridge/com.ucp.bridge/Editor.meta +8 -0
  69. package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef +14 -0
  70. package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef.meta +7 -0
  71. package/bridge/com.ucp.bridge/Runtime.meta +8 -0
  72. package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs +1085 -0
  73. package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs.meta +2 -0
  74. package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef +12 -0
  75. package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef.meta +7 -0
  76. package/bridge/com.ucp.bridge/Tests/Editor.meta +8 -0
  77. package/bridge/com.ucp.bridge/Tests.meta +8 -0
  78. package/bridge/com.ucp.bridge/package.json +27 -0
  79. package/bridge/com.ucp.bridge/package.json.meta +7 -0
  80. package/package.json +2 -2
  81. package/scripts/install.js +4 -6
@@ -0,0 +1,326 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using UnityEditor;
4
+ using UnityEditor.SceneManagement;
5
+ using UnityEngine;
6
+ using UnityEngine.SceneManagement;
7
+
8
+ namespace UCP.Bridge
9
+ {
10
+ public static class HierarchyController
11
+ {
12
+ public static void Register(CommandRouter router)
13
+ {
14
+ router.Register("object/create", HandleCreate);
15
+ router.Register("object/delete", HandleDelete);
16
+ router.Register("object/reparent", HandleReparent);
17
+ router.Register("object/instantiate", HandleInstantiate);
18
+ router.Register("object/add-component", HandleAddComponent);
19
+ router.Register("object/remove-component", HandleRemoveComponent);
20
+ }
21
+
22
+ private static object HandleCreate(string paramsJson)
23
+ {
24
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
25
+ var name = "GameObject";
26
+ if (p != null && p.TryGetValue("name", out var nameObj) && nameObj != null)
27
+ name = nameObj.ToString();
28
+
29
+ var go = new GameObject(name);
30
+ Undo.RegisterCreatedObjectUndo(go, "UCP Create GameObject");
31
+
32
+ // Optional parent
33
+ if (p != null && p.TryGetValue("parent", out var parentObj))
34
+ {
35
+ int parentId = Convert.ToInt32(parentObj);
36
+ var parent = FindGameObject(parentId);
37
+ go.transform.SetParent(parent.transform, false);
38
+ }
39
+
40
+ // Optional position
41
+ if (p != null && p.TryGetValue("position", out var posObj) && posObj is List<object> pos && pos.Count >= 3)
42
+ {
43
+ go.transform.localPosition = new Vector3(
44
+ Convert.ToSingle(pos[0]),
45
+ Convert.ToSingle(pos[1]),
46
+ Convert.ToSingle(pos[2]));
47
+ }
48
+
49
+ // Optional rotation (euler angles)
50
+ if (p != null && p.TryGetValue("rotation", out var rotObj) && rotObj is List<object> rot && rot.Count >= 3)
51
+ {
52
+ go.transform.localEulerAngles = new Vector3(
53
+ Convert.ToSingle(rot[0]),
54
+ Convert.ToSingle(rot[1]),
55
+ Convert.ToSingle(rot[2]));
56
+ }
57
+
58
+ EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
59
+ SceneChangeTracker.RecordGameObjectChange(go, "GameObject");
60
+
61
+ return new Dictionary<string, object>
62
+ {
63
+ ["status"] = "ok",
64
+ ["instanceId"] = go.GetInstanceID(),
65
+ ["name"] = go.name
66
+ };
67
+ }
68
+
69
+ private static object HandleDelete(string paramsJson)
70
+ {
71
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
72
+ if (p == null || !p.TryGetValue("instanceId", out var idObj))
73
+ throw new ArgumentException("Missing 'instanceId' parameter");
74
+
75
+ int instanceId = Convert.ToInt32(idObj);
76
+ var go = FindGameObject(instanceId);
77
+ string name = go.name;
78
+ var scene = go.scene;
79
+
80
+ Undo.DestroyObjectImmediate(go);
81
+ EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
82
+ SceneChangeTracker.RecordDeletedObject(scene, instanceId, name, "GameObject");
83
+
84
+ return new Dictionary<string, object>
85
+ {
86
+ ["status"] = "ok",
87
+ ["deleted"] = name,
88
+ ["instanceId"] = instanceId
89
+ };
90
+ }
91
+
92
+ private static object HandleReparent(string paramsJson)
93
+ {
94
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
95
+ if (p == null || !p.TryGetValue("instanceId", out var idObj))
96
+ throw new ArgumentException("Missing 'instanceId' parameter");
97
+
98
+ int instanceId = Convert.ToInt32(idObj);
99
+ var go = FindGameObject(instanceId);
100
+
101
+ Undo.SetTransformParent(go.transform, null, "UCP Reparent");
102
+
103
+ if (p.TryGetValue("parent", out var parentObj) && parentObj != null)
104
+ {
105
+ int parentId = Convert.ToInt32(parentObj);
106
+ var parent = FindGameObject(parentId);
107
+ Undo.SetTransformParent(go.transform, parent.transform, "UCP Reparent");
108
+ }
109
+ // else: parent = null means move to root
110
+
111
+ // Optional sibling index
112
+ if (p.TryGetValue("siblingIndex", out var sibObj))
113
+ {
114
+ go.transform.SetSiblingIndex(Convert.ToInt32(sibObj));
115
+ }
116
+
117
+ EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
118
+ SceneChangeTracker.RecordGameObjectChange(go, "Transform");
119
+
120
+ return new Dictionary<string, object>
121
+ {
122
+ ["status"] = "ok",
123
+ ["instanceId"] = instanceId,
124
+ ["name"] = go.name,
125
+ ["parent"] = go.transform.parent != null ? go.transform.parent.gameObject.name : null
126
+ };
127
+ }
128
+
129
+ private static object HandleInstantiate(string paramsJson)
130
+ {
131
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
132
+ if (p == null)
133
+ throw new ArgumentException("Missing parameters");
134
+
135
+ GameObject source = null;
136
+
137
+ // Instantiate from prefab asset path
138
+ if (p.TryGetValue("prefab", out var prefabObj) && prefabObj != null)
139
+ {
140
+ string prefabPath = prefabObj.ToString();
141
+ var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
142
+ if (prefab == null)
143
+ throw new ArgumentException($"Prefab not found: {prefabPath}");
144
+ source = prefab;
145
+ }
146
+ // Instantiate from existing scene object (clone)
147
+ else if (p.TryGetValue("sourceId", out var srcObj))
148
+ {
149
+ int srcId = Convert.ToInt32(srcObj);
150
+ source = FindGameObject(srcId);
151
+ }
152
+ else
153
+ {
154
+ throw new ArgumentException("Must provide 'prefab' (asset path) or 'sourceId' (instanceId)");
155
+ }
156
+
157
+ var instance = (GameObject)PrefabUtility.InstantiatePrefab(source);
158
+ if (instance == null)
159
+ {
160
+ // Fallback for non-prefab objects (e.g. cloning scene objects)
161
+ instance = UnityEngine.Object.Instantiate(source);
162
+ }
163
+
164
+ Undo.RegisterCreatedObjectUndo(instance, "UCP Instantiate");
165
+
166
+ // Optional parent
167
+ if (p.TryGetValue("parent", out var parentObj) && parentObj != null)
168
+ {
169
+ int parentId = Convert.ToInt32(parentObj);
170
+ var parent = FindGameObject(parentId);
171
+ instance.transform.SetParent(parent.transform, false);
172
+ }
173
+
174
+ // Optional name override
175
+ if (p.TryGetValue("name", out var nameObj) && nameObj != null)
176
+ {
177
+ instance.name = nameObj.ToString();
178
+ }
179
+
180
+ // Optional position
181
+ if (p.TryGetValue("position", out var posObj) && posObj is List<object> pos && pos.Count >= 3)
182
+ {
183
+ instance.transform.localPosition = new Vector3(
184
+ Convert.ToSingle(pos[0]),
185
+ Convert.ToSingle(pos[1]),
186
+ Convert.ToSingle(pos[2]));
187
+ }
188
+
189
+ EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
190
+ SceneChangeTracker.RecordGameObjectChange(instance, "GameObject");
191
+
192
+ return new Dictionary<string, object>
193
+ {
194
+ ["status"] = "ok",
195
+ ["instanceId"] = instance.GetInstanceID(),
196
+ ["name"] = instance.name
197
+ };
198
+ }
199
+
200
+ private static object HandleAddComponent(string paramsJson)
201
+ {
202
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
203
+ if (p == null || !p.TryGetValue("instanceId", out var idObj))
204
+ throw new ArgumentException("Missing 'instanceId' parameter");
205
+ if (!p.TryGetValue("type", out var typeObj) || typeObj == null)
206
+ throw new ArgumentException("Missing 'type' parameter");
207
+
208
+ int instanceId = Convert.ToInt32(idObj);
209
+ var go = FindGameObject(instanceId);
210
+ string typeName = typeObj.ToString();
211
+
212
+ // Resolve component type
213
+ Type compType = ResolveComponentType(typeName);
214
+ if (compType == null)
215
+ throw new ArgumentException($"Component type not found: {typeName}");
216
+
217
+ var comp = Undo.AddComponent(go, compType);
218
+ EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
219
+ SceneChangeTracker.RecordGameObjectChange(go, comp.GetType().Name);
220
+
221
+ return new Dictionary<string, object>
222
+ {
223
+ ["status"] = "ok",
224
+ ["instanceId"] = instanceId,
225
+ ["component"] = comp.GetType().Name,
226
+ ["componentFullType"] = comp.GetType().FullName
227
+ };
228
+ }
229
+
230
+ private static object HandleRemoveComponent(string paramsJson)
231
+ {
232
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
233
+ if (p == null || !p.TryGetValue("instanceId", out var idObj))
234
+ throw new ArgumentException("Missing 'instanceId' parameter");
235
+ if (!p.TryGetValue("type", out var typeObj) || typeObj == null)
236
+ throw new ArgumentException("Missing 'type' parameter");
237
+
238
+ int instanceId = Convert.ToInt32(idObj);
239
+ var go = FindGameObject(instanceId);
240
+ string typeName = typeObj.ToString();
241
+
242
+ Component target = null;
243
+ foreach (var c in go.GetComponents<Component>())
244
+ {
245
+ if (c == null) continue;
246
+ if (c.GetType().Name == typeName || c.GetType().FullName == typeName)
247
+ {
248
+ target = c;
249
+ break;
250
+ }
251
+ }
252
+
253
+ if (target == null)
254
+ throw new ArgumentException($"Component '{typeName}' not found on '{go.name}'");
255
+ if (target is Transform)
256
+ throw new ArgumentException("Cannot remove Transform component");
257
+
258
+ Undo.DestroyObjectImmediate(target);
259
+ EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
260
+ SceneChangeTracker.RecordGameObjectChange(go, typeName);
261
+
262
+ return new Dictionary<string, object>
263
+ {
264
+ ["status"] = "ok",
265
+ ["instanceId"] = instanceId,
266
+ ["removed"] = typeName
267
+ };
268
+ }
269
+
270
+ private static Type ResolveComponentType(string typeName)
271
+ {
272
+ // Try exact match first
273
+ var type = Type.GetType(typeName);
274
+ if (type != null && typeof(Component).IsAssignableFrom(type))
275
+ return type;
276
+
277
+ // Search Unity assemblies
278
+ foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
279
+ {
280
+ foreach (var t in assembly.GetTypes())
281
+ {
282
+ if (!typeof(Component).IsAssignableFrom(t)) continue;
283
+ if (t.Name == typeName || t.FullName == typeName)
284
+ return t;
285
+ }
286
+ }
287
+
288
+ // Common Unity types fallback
289
+ var unityType = Type.GetType($"UnityEngine.{typeName}, UnityEngine.CoreModule");
290
+ if (unityType != null && typeof(Component).IsAssignableFrom(unityType))
291
+ return unityType;
292
+
293
+ return null;
294
+ }
295
+
296
+ private static GameObject FindGameObject(int instanceId)
297
+ {
298
+ var obj = EditorUtility.EntityIdToObject(instanceId) as GameObject;
299
+ if (obj != null) return obj;
300
+
301
+ for (int i = 0; i < SceneManager.sceneCount; i++)
302
+ {
303
+ var scene = SceneManager.GetSceneAt(i);
304
+ if (!scene.isLoaded) continue;
305
+ foreach (var root in scene.GetRootGameObjects())
306
+ {
307
+ var found = FindInHierarchy(root, instanceId);
308
+ if (found != null) return found;
309
+ }
310
+ }
311
+
312
+ throw new ArgumentException($"GameObject not found: {instanceId}");
313
+ }
314
+
315
+ private static GameObject FindInHierarchy(GameObject go, int instanceId)
316
+ {
317
+ if (go.GetInstanceID() == instanceId) return go;
318
+ for (int i = 0; i < go.transform.childCount; i++)
319
+ {
320
+ var found = FindInHierarchy(go.transform.GetChild(i).gameObject, instanceId);
321
+ if (found != null) return found;
322
+ }
323
+ return null;
324
+ }
325
+ }
326
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 8d90db77ca2967941a28a26f7af1adfe
@@ -0,0 +1,209 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using UnityEditor;
4
+
5
+ namespace UCP.Bridge
6
+ {
7
+ public static class ImporterController
8
+ {
9
+ public static void Register(CommandRouter router)
10
+ {
11
+ router.Register("asset/reimport", HandleReimport);
12
+ router.Register("asset/import-settings/read", HandleRead);
13
+ router.Register("asset/import-settings/write", HandleWrite);
14
+ router.Register("asset/import-settings/write-batch", HandleWriteBatch);
15
+ }
16
+
17
+ private static object HandleReimport(string paramsJson)
18
+ {
19
+ var parameters = ParseParameters(paramsJson);
20
+ var requestedPath = RequirePath(parameters);
21
+ return AssetImportSupport.Reimport(requestedPath);
22
+ }
23
+
24
+ private static object HandleRead(string paramsJson)
25
+ {
26
+ var parameters = ParseParameters(paramsJson);
27
+ var requestedPath = RequirePath(parameters);
28
+ var importer = AssetImportSupport.ResolveImporter(requestedPath);
29
+ var serializedObject = new SerializedObject(importer);
30
+ var fields = new List<object>();
31
+
32
+ try
33
+ {
34
+ if (TryGetOptionalString(parameters, "field", out var fieldName))
35
+ {
36
+ var property = serializedObject.FindProperty(fieldName);
37
+ if (property == null)
38
+ throw new ArgumentException($"Field '{fieldName}' not found on {importer.GetType().Name}");
39
+
40
+ fields.Add(SerializedPropertyControllerSupport.Describe(property));
41
+ }
42
+ else
43
+ {
44
+ var iterator = serializedObject.GetIterator();
45
+ if (iterator.NextVisible(true))
46
+ {
47
+ do
48
+ {
49
+ fields.Add(SerializedPropertyControllerSupport.Describe(iterator));
50
+ }
51
+ while (iterator.NextVisible(false));
52
+ }
53
+ }
54
+
55
+ return CreateImporterPayload(requestedPath, importer, fields);
56
+ }
57
+ finally
58
+ {
59
+ serializedObject.Dispose();
60
+ }
61
+ }
62
+
63
+ private static object HandleWrite(string paramsJson)
64
+ {
65
+ var parameters = ParseParameters(paramsJson);
66
+ var requestedPath = RequirePath(parameters);
67
+ if (!parameters.TryGetValue("field", out var fieldObject) || fieldObject == null)
68
+ throw new ArgumentException("Missing 'field' parameter");
69
+ if (!parameters.ContainsKey("value"))
70
+ throw new ArgumentException("Missing 'value' parameter");
71
+
72
+ var importer = AssetImportSupport.ResolveImporter(requestedPath);
73
+ var fieldName = fieldObject.ToString();
74
+ var noReimport = TryGetOptionalBool(parameters, "noReimport");
75
+ var serializedObject = new SerializedObject(importer);
76
+
77
+ try
78
+ {
79
+ Undo.RecordObject(importer, $"UCP Importer Write {fieldName}");
80
+ SerializedPropertyControllerSupport.WriteFieldValue(
81
+ serializedObject,
82
+ importer.GetType().Name,
83
+ fieldName,
84
+ parameters["value"]);
85
+ serializedObject.ApplyModifiedProperties();
86
+
87
+ return new Dictionary<string, object>
88
+ {
89
+ ["status"] = "ok",
90
+ ["path"] = requestedPath,
91
+ ["assetPath"] = AssetImportSupport.GetPrimaryAssetPath(requestedPath),
92
+ ["importerType"] = importer.GetType().Name,
93
+ ["field"] = fieldName,
94
+ ["reimport"] = AssetImportSupport.SaveImporterSettings(requestedPath, importer, noReimport)
95
+ };
96
+ }
97
+ finally
98
+ {
99
+ serializedObject.Dispose();
100
+ }
101
+ }
102
+
103
+ private static object HandleWriteBatch(string paramsJson)
104
+ {
105
+ var parameters = ParseParameters(paramsJson);
106
+ var requestedPath = RequirePath(parameters);
107
+ if (!parameters.TryGetValue("values", out var valuesObject) || !(valuesObject is Dictionary<string, object> values))
108
+ throw new ArgumentException("Missing 'values' parameter");
109
+
110
+ var importer = AssetImportSupport.ResolveImporter(requestedPath);
111
+ var noReimport = TryGetOptionalBool(parameters, "noReimport");
112
+ var serializedObject = new SerializedObject(importer);
113
+ var fields = new List<object>();
114
+
115
+ try
116
+ {
117
+ Undo.RecordObject(importer, $"UCP Importer Batch Write {importer.name}");
118
+
119
+ foreach (var entry in values)
120
+ {
121
+ SerializedPropertyControllerSupport.WriteFieldValue(
122
+ serializedObject,
123
+ importer.GetType().Name,
124
+ entry.Key,
125
+ entry.Value);
126
+ fields.Add(entry.Key);
127
+ }
128
+
129
+ serializedObject.ApplyModifiedProperties();
130
+
131
+ return new Dictionary<string, object>
132
+ {
133
+ ["status"] = "ok",
134
+ ["path"] = requestedPath,
135
+ ["assetPath"] = AssetImportSupport.GetPrimaryAssetPath(requestedPath),
136
+ ["importerType"] = importer.GetType().Name,
137
+ ["fields"] = fields,
138
+ ["reimport"] = AssetImportSupport.SaveImporterSettings(requestedPath, importer, noReimport)
139
+ };
140
+ }
141
+ finally
142
+ {
143
+ serializedObject.Dispose();
144
+ }
145
+ }
146
+
147
+ private static Dictionary<string, object> CreateImporterPayload(
148
+ string requestedPath,
149
+ AssetImporter importer,
150
+ List<object> fields)
151
+ {
152
+ var assetPath = AssetImportSupport.GetPrimaryAssetPath(requestedPath);
153
+ var mainAsset = AssetDatabase.LoadMainAssetAtPath(assetPath);
154
+
155
+ var payload = new Dictionary<string, object>
156
+ {
157
+ ["path"] = requestedPath,
158
+ ["assetPath"] = assetPath,
159
+ ["metaPath"] = assetPath + ".meta",
160
+ ["importerType"] = importer.GetType().Name,
161
+ ["fields"] = fields
162
+ };
163
+
164
+ if (mainAsset != null)
165
+ {
166
+ payload["assetName"] = mainAsset.name;
167
+ payload["assetType"] = mainAsset.GetType().Name;
168
+ }
169
+
170
+ return payload;
171
+ }
172
+
173
+ private static Dictionary<string, object> ParseParameters(string paramsJson)
174
+ {
175
+ return MiniJson.Deserialize(paramsJson) as Dictionary<string, object>
176
+ ?? throw new ArgumentException("Invalid parameters");
177
+ }
178
+
179
+ private static string RequirePath(Dictionary<string, object> parameters)
180
+ {
181
+ if (!parameters.TryGetValue("path", out var pathObject) || pathObject == null)
182
+ throw new ArgumentException("Missing 'path' parameter");
183
+
184
+ return pathObject.ToString();
185
+ }
186
+
187
+ private static bool TryGetOptionalString(
188
+ Dictionary<string, object> parameters,
189
+ string key,
190
+ out string value)
191
+ {
192
+ if (parameters.TryGetValue(key, out var valueObject) && valueObject != null)
193
+ {
194
+ value = valueObject.ToString();
195
+ return true;
196
+ }
197
+
198
+ value = null;
199
+ return false;
200
+ }
201
+
202
+ private static bool TryGetOptionalBool(Dictionary<string, object> parameters, string key)
203
+ {
204
+ return parameters.TryGetValue(key, out var valueObject)
205
+ && valueObject != null
206
+ && Convert.ToBoolean(valueObject);
207
+ }
208
+ }
209
+ }
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 6c9bb0fa5d494cab8f4055d53d9e2812