@mflrevan/ucp 0.4.4 → 0.4.6
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/README.md +1 -1
- package/bridge/com.ucp.bridge/CHANGELOG.md +145 -0
- package/bridge/com.ucp.bridge/CHANGELOG.md.meta +7 -0
- package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs +583 -0
- package/bridge/com.ucp.bridge/Editor/Bridge/BridgeServer.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Bridge.meta +8 -0
- package/bridge/com.ucp.bridge/Editor/Compatibility/UnityObjectCompat.cs +18 -0
- package/bridge/com.ucp.bridge/Editor/Compatibility/UnityObjectCompat.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Compatibility.meta +8 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs +425 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/AssetController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/AssetImportSupport.cs +355 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/AssetImportSupport.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs +233 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/BuildController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs +26 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/CompilationController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs +31 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs +527 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/EditorSettingsController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs +141 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/FileController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs +326 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/HierarchyController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ImporterController.cs +209 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ImporterController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs +409 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/LogsController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs +354 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/MaterialController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs +93 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ObjectReferenceResolver.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PackagesController.cs +503 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PackagesController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs +188 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PlayModeController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs +260 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PrefabController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ProfilerController.cs +1679 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ProfilerController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs +579 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/PropertyController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneChangeTracker.cs +166 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneChangeTracker.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs +318 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SceneController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs +125 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ScreenshotController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs +104 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/ScriptController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs +227 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/SnapshotController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs +240 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/TestRunnerController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs +611 -0
- package/bridge/com.ucp.bridge/Editor/Controllers/VcsController.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Controllers.meta +8 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs +53 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/CommandRouter.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs +80 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/MessageTypes.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs +358 -0
- package/bridge/com.ucp.bridge/Editor/Protocol/MiniJson.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Protocol.meta +8 -0
- package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs +37 -0
- package/bridge/com.ucp.bridge/Editor/Scripts/IUCPScript.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Editor/Scripts.meta +8 -0
- package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef +18 -0
- package/bridge/com.ucp.bridge/Editor/UCP.Bridge.Editor.asmdef.meta +7 -0
- package/bridge/com.ucp.bridge/Editor.meta +8 -0
- package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef +14 -0
- package/bridge/com.ucp.bridge/Runtime/UCP.Bridge.Runtime.asmdef.meta +7 -0
- package/bridge/com.ucp.bridge/Runtime.meta +8 -0
- package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs +1085 -0
- package/bridge/com.ucp.bridge/Tests/Editor/ControllerSmokeTests.cs.meta +2 -0
- package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef +12 -0
- package/bridge/com.ucp.bridge/Tests/Editor/UCP.Bridge.Editor.Tests.asmdef.meta +7 -0
- package/bridge/com.ucp.bridge/Tests/Editor.meta +8 -0
- package/bridge/com.ucp.bridge/Tests.meta +8 -0
- package/bridge/com.ucp.bridge/package.json +29 -0
- package/bridge/com.ucp.bridge/package.json.meta +7 -0
- package/package.json +2 -2
- 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 = UnityObjectCompat.ResolveByInstanceId<GameObject>(instanceId);
|
|
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,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
|
+
}
|