@mflrevan/ucp 0.4.4 → 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,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 5d45d1b5685289d42b2ea1456f239976
@@ -0,0 +1,563 @@
1
+ using System;
2
+ using System.Collections;
3
+ using System.Collections.Generic;
4
+ using System.Reflection;
5
+ using UnityEditor;
6
+ using UnityEditor.SceneManagement;
7
+ using UnityEngine;
8
+ using UnityEngine.SceneManagement;
9
+
10
+ namespace UCP.Bridge
11
+ {
12
+ public static class PropertyController
13
+ {
14
+ public static void Register(CommandRouter router)
15
+ {
16
+ router.Register("object/get-fields", HandleGetFields);
17
+ router.Register("object/get-property", HandleGetProperty);
18
+ router.Register("object/set-property", HandleSetProperty);
19
+ router.Register("object/set-active", HandleSetActive);
20
+ router.Register("object/set-name", HandleSetName);
21
+ }
22
+
23
+ private static object HandleGetFields(string paramsJson)
24
+ {
25
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
26
+ if (p == null || !p.TryGetValue("instanceId", out var idObj))
27
+ throw new ArgumentException("Missing 'instanceId' parameter");
28
+
29
+ var componentType = p.TryGetValue("component", out var cObj) ? cObj?.ToString() : null;
30
+ int instanceId = Convert.ToInt32(idObj);
31
+ var go = FindGameObject(instanceId);
32
+
33
+ if (componentType != null)
34
+ {
35
+ var comp = FindComponent(go, componentType);
36
+ return new Dictionary<string, object>
37
+ {
38
+ ["instanceId"] = instanceId,
39
+ ["name"] = go.name,
40
+ ["component"] = componentType,
41
+ ["fields"] = SerializeComponentFields(comp)
42
+ };
43
+ }
44
+
45
+ // Return fields for all components
46
+ var allComponents = new List<object>();
47
+ foreach (var c in go.GetComponents<Component>())
48
+ {
49
+ if (c == null) continue;
50
+ allComponents.Add(new Dictionary<string, object>
51
+ {
52
+ ["type"] = c.GetType().Name,
53
+ ["fields"] = SerializeComponentFields(c)
54
+ });
55
+ }
56
+
57
+ return new Dictionary<string, object>
58
+ {
59
+ ["instanceId"] = instanceId,
60
+ ["name"] = go.name,
61
+ ["components"] = allComponents
62
+ };
63
+ }
64
+
65
+ private static object HandleGetProperty(string paramsJson)
66
+ {
67
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
68
+ if (p == null || !p.TryGetValue("instanceId", out var idObj))
69
+ throw new ArgumentException("Missing 'instanceId' parameter");
70
+ if (!p.TryGetValue("component", out var cObj) || cObj == null)
71
+ throw new ArgumentException("Missing 'component' parameter");
72
+ if (!p.TryGetValue("property", out var propObj) || propObj == null)
73
+ throw new ArgumentException("Missing 'property' parameter");
74
+
75
+ int instanceId = Convert.ToInt32(idObj);
76
+ var go = FindGameObject(instanceId);
77
+ var comp = FindComponent(go, cObj.ToString());
78
+ string propName = propObj.ToString();
79
+
80
+ var value = GetPropertyValue(comp, propName);
81
+ return new Dictionary<string, object>
82
+ {
83
+ ["instanceId"] = instanceId,
84
+ ["component"] = cObj.ToString(),
85
+ ["property"] = propName,
86
+ ["value"] = ConvertToJson(value),
87
+ ["type"] = value != null ? value.GetType().Name : "null"
88
+ };
89
+ }
90
+
91
+ private static object HandleSetProperty(string paramsJson)
92
+ {
93
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
94
+ if (p == null || !p.TryGetValue("instanceId", out var idObj))
95
+ throw new ArgumentException("Missing 'instanceId' parameter");
96
+ if (!p.TryGetValue("component", out var cObj) || cObj == null)
97
+ throw new ArgumentException("Missing 'component' parameter");
98
+ if (!p.TryGetValue("property", out var propObj) || propObj == null)
99
+ throw new ArgumentException("Missing 'property' parameter");
100
+ if (!p.ContainsKey("value"))
101
+ throw new ArgumentException("Missing 'value' parameter");
102
+
103
+ int instanceId = Convert.ToInt32(idObj);
104
+ var go = FindGameObject(instanceId);
105
+ var comp = FindComponent(go, cObj.ToString());
106
+ string propName = propObj.ToString();
107
+
108
+ Undo.RecordObject(comp, $"UCP Set {propName}");
109
+ SetPropertyValue(comp, propName, p["value"]);
110
+ EditorUtility.SetDirty(comp);
111
+ UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
112
+ SceneChangeTracker.RecordGameObjectChange(go, comp.GetType().Name);
113
+
114
+ return new Dictionary<string, object>
115
+ {
116
+ ["status"] = "ok",
117
+ ["instanceId"] = instanceId,
118
+ ["component"] = cObj.ToString(),
119
+ ["property"] = propName
120
+ };
121
+ }
122
+
123
+ private static object HandleSetActive(string paramsJson)
124
+ {
125
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
126
+ if (p == null || !p.TryGetValue("instanceId", out var idObj))
127
+ throw new ArgumentException("Missing 'instanceId' parameter");
128
+ if (!p.TryGetValue("active", out var activeObj))
129
+ throw new ArgumentException("Missing 'active' parameter");
130
+
131
+ int instanceId = Convert.ToInt32(idObj);
132
+ var go = FindGameObject(instanceId);
133
+
134
+ Undo.RecordObject(go, "UCP Set Active");
135
+ go.SetActive(Convert.ToBoolean(activeObj));
136
+ EditorUtility.SetDirty(go);
137
+ UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
138
+ SceneChangeTracker.RecordGameObjectChange(go, "GameObject");
139
+
140
+ return new Dictionary<string, object>
141
+ {
142
+ ["status"] = "ok",
143
+ ["instanceId"] = instanceId,
144
+ ["active"] = go.activeSelf
145
+ };
146
+ }
147
+
148
+ private static object HandleSetName(string paramsJson)
149
+ {
150
+ var p = MiniJson.Deserialize(paramsJson) as Dictionary<string, object>;
151
+ if (p == null || !p.TryGetValue("instanceId", out var idObj))
152
+ throw new ArgumentException("Missing 'instanceId' parameter");
153
+ if (!p.TryGetValue("name", out var nameObj) || nameObj == null)
154
+ throw new ArgumentException("Missing 'name' parameter");
155
+
156
+ int instanceId = Convert.ToInt32(idObj);
157
+ var go = FindGameObject(instanceId);
158
+
159
+ Undo.RecordObject(go, "UCP Rename");
160
+ go.name = nameObj.ToString();
161
+ EditorUtility.SetDirty(go);
162
+ UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
163
+ SceneChangeTracker.RecordGameObjectChange(go, "GameObject");
164
+
165
+ return new Dictionary<string, object>
166
+ {
167
+ ["status"] = "ok",
168
+ ["instanceId"] = instanceId,
169
+ ["name"] = go.name
170
+ };
171
+ }
172
+
173
+ // ---- Reflection helpers ----
174
+
175
+ private static List<object> SerializeComponentFields(Component comp)
176
+ {
177
+ var fields = new List<object>();
178
+ var type = comp.GetType();
179
+
180
+ // Use SerializedObject for reliable Unity property enumeration
181
+ var so = new SerializedObject(comp);
182
+ var prop = so.GetIterator();
183
+ if (prop.NextVisible(true))
184
+ {
185
+ do
186
+ {
187
+ var fieldDict = new Dictionary<string, object>
188
+ {
189
+ ["name"] = prop.name,
190
+ ["displayName"] = prop.displayName,
191
+ ["type"] = prop.propertyType.ToString(),
192
+ ["editable"] = !prop.isReadOnly(true)
193
+ };
194
+
195
+ try
196
+ {
197
+ fieldDict["value"] = SerializedPropertyToValue(prop);
198
+ }
199
+ catch
200
+ {
201
+ fieldDict["value"] = "<unreadable>";
202
+ }
203
+
204
+ fields.Add(fieldDict);
205
+ }
206
+ while (prop.NextVisible(false));
207
+ }
208
+ so.Dispose();
209
+
210
+ return fields;
211
+ }
212
+
213
+ private static object SerializedPropertyToValue(SerializedProperty prop)
214
+ {
215
+ switch (prop.propertyType)
216
+ {
217
+ case SerializedPropertyType.Integer:
218
+ return prop.intValue;
219
+ case SerializedPropertyType.Boolean:
220
+ return prop.boolValue;
221
+ case SerializedPropertyType.Float:
222
+ return (double)prop.floatValue;
223
+ case SerializedPropertyType.String:
224
+ return prop.stringValue;
225
+ case SerializedPropertyType.Color:
226
+ var c = prop.colorValue;
227
+ return new List<object> { (double)c.r, (double)c.g, (double)c.b, (double)c.a };
228
+ case SerializedPropertyType.ObjectReference:
229
+ return ObjectReferenceResolver.Serialize(prop.objectReferenceValue);
230
+ case SerializedPropertyType.LayerMask:
231
+ return prop.intValue;
232
+ case SerializedPropertyType.Enum:
233
+ return prop.enumValueIndex < prop.enumDisplayNames.Length
234
+ ? prop.enumDisplayNames[prop.enumValueIndex]
235
+ : prop.enumValueIndex.ToString();
236
+ case SerializedPropertyType.Vector2:
237
+ var v2 = prop.vector2Value;
238
+ return new List<object> { (double)v2.x, (double)v2.y };
239
+ case SerializedPropertyType.Vector3:
240
+ var v3 = prop.vector3Value;
241
+ return new List<object> { (double)v3.x, (double)v3.y, (double)v3.z };
242
+ case SerializedPropertyType.Vector4:
243
+ var v4 = prop.vector4Value;
244
+ return new List<object> { (double)v4.x, (double)v4.y, (double)v4.z, (double)v4.w };
245
+ case SerializedPropertyType.Rect:
246
+ var r = prop.rectValue;
247
+ return new Dictionary<string, object>
248
+ {
249
+ ["x"] = (double)r.x,
250
+ ["y"] = (double)r.y,
251
+ ["width"] = (double)r.width,
252
+ ["height"] = (double)r.height
253
+ };
254
+ case SerializedPropertyType.Bounds:
255
+ var b = prop.boundsValue;
256
+ return new Dictionary<string, object>
257
+ {
258
+ ["center"] = new List<object> { (double)b.center.x, (double)b.center.y, (double)b.center.z },
259
+ ["size"] = new List<object> { (double)b.size.x, (double)b.size.y, (double)b.size.z }
260
+ };
261
+ case SerializedPropertyType.Quaternion:
262
+ var q = prop.quaternionValue;
263
+ return new List<object> { (double)q.x, (double)q.y, (double)q.z, (double)q.w };
264
+ case SerializedPropertyType.AnimationCurve:
265
+ return "<AnimationCurve>";
266
+ case SerializedPropertyType.Gradient:
267
+ return "<Gradient>";
268
+ default:
269
+ return $"<{prop.propertyType}>";
270
+ }
271
+ }
272
+
273
+ private static object GetPropertyValue(Component comp, string propertyName)
274
+ {
275
+ var so = new SerializedObject(comp);
276
+ var prop = so.FindProperty(propertyName);
277
+ if (prop != null)
278
+ {
279
+ var val = SerializedPropertyToValue(prop);
280
+ so.Dispose();
281
+ return val;
282
+ }
283
+ so.Dispose();
284
+
285
+ // Fallback to reflection
286
+ var type = comp.GetType();
287
+ var fi = type.GetField(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
288
+ if (fi != null)
289
+ return fi.GetValue(comp);
290
+
291
+ var pi = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
292
+ if (pi != null && pi.CanRead)
293
+ return pi.GetValue(comp);
294
+
295
+ throw new ArgumentException($"Property '{propertyName}' not found on {type.Name}");
296
+ }
297
+
298
+ private static void SetPropertyValue(Component comp, string propertyName, object jsonValue)
299
+ {
300
+ var so = new SerializedObject(comp);
301
+ var prop = so.FindProperty(propertyName);
302
+ if (prop != null)
303
+ {
304
+ SetSerializedPropertyValue(prop, jsonValue);
305
+ so.ApplyModifiedProperties();
306
+ so.Dispose();
307
+ return;
308
+ }
309
+ so.Dispose();
310
+
311
+ // Fallback to reflection
312
+ var type = comp.GetType();
313
+ var fi = type.GetField(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
314
+ if (fi != null)
315
+ {
316
+ fi.SetValue(comp, ConvertFromJson(jsonValue, fi.FieldType));
317
+ return;
318
+ }
319
+
320
+ var pi = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
321
+ if (pi != null && pi.CanWrite)
322
+ {
323
+ pi.SetValue(comp, ConvertFromJson(jsonValue, pi.PropertyType));
324
+ return;
325
+ }
326
+
327
+ throw new ArgumentException($"Property '{propertyName}' not found or not writable on {type.Name}");
328
+ }
329
+
330
+ private static void SetSerializedPropertyValue(SerializedProperty prop, object value)
331
+ {
332
+ if (prop.isArray && prop.propertyType == SerializedPropertyType.Generic)
333
+ {
334
+ SetSerializedArrayValue(prop, value);
335
+ return;
336
+ }
337
+
338
+ switch (prop.propertyType)
339
+ {
340
+ case SerializedPropertyType.Integer:
341
+ prop.intValue = Convert.ToInt32(value);
342
+ break;
343
+ case SerializedPropertyType.Boolean:
344
+ prop.boolValue = Convert.ToBoolean(value);
345
+ break;
346
+ case SerializedPropertyType.Float:
347
+ prop.floatValue = Convert.ToSingle(value);
348
+ break;
349
+ case SerializedPropertyType.String:
350
+ prop.stringValue = value?.ToString() ?? "";
351
+ break;
352
+ case SerializedPropertyType.Color:
353
+ var cArr = value as List<object>;
354
+ if (cArr != null && cArr.Count >= 3)
355
+ prop.colorValue = new Color(
356
+ Convert.ToSingle(cArr[0]),
357
+ Convert.ToSingle(cArr[1]),
358
+ Convert.ToSingle(cArr[2]),
359
+ cArr.Count >= 4 ? Convert.ToSingle(cArr[3]) : 1f);
360
+ break;
361
+ case SerializedPropertyType.Enum:
362
+ if (value is string enumStr)
363
+ {
364
+ int idx = Array.IndexOf(prop.enumDisplayNames, enumStr);
365
+ if (idx >= 0)
366
+ prop.enumValueIndex = idx;
367
+ else if (int.TryParse(enumStr, out int enumIdx))
368
+ prop.enumValueIndex = enumIdx;
369
+ else
370
+ throw new ArgumentException($"Invalid enum value: {enumStr}");
371
+ }
372
+ else
373
+ {
374
+ prop.enumValueIndex = Convert.ToInt32(value);
375
+ }
376
+ break;
377
+ case SerializedPropertyType.Vector2:
378
+ var v2Arr = value as List<object>;
379
+ if (v2Arr != null && v2Arr.Count >= 2)
380
+ prop.vector2Value = new Vector2(
381
+ Convert.ToSingle(v2Arr[0]),
382
+ Convert.ToSingle(v2Arr[1]));
383
+ break;
384
+ case SerializedPropertyType.Vector3:
385
+ var v3Arr = value as List<object>;
386
+ if (v3Arr != null && v3Arr.Count >= 3)
387
+ prop.vector3Value = new Vector3(
388
+ Convert.ToSingle(v3Arr[0]),
389
+ Convert.ToSingle(v3Arr[1]),
390
+ Convert.ToSingle(v3Arr[2]));
391
+ break;
392
+ case SerializedPropertyType.Vector4:
393
+ var v4Arr = value as List<object>;
394
+ if (v4Arr != null && v4Arr.Count >= 4)
395
+ prop.vector4Value = new Vector4(
396
+ Convert.ToSingle(v4Arr[0]),
397
+ Convert.ToSingle(v4Arr[1]),
398
+ Convert.ToSingle(v4Arr[2]),
399
+ Convert.ToSingle(v4Arr[3]));
400
+ break;
401
+ case SerializedPropertyType.Quaternion:
402
+ var qArr = value as List<object>;
403
+ if (qArr != null && qArr.Count >= 4)
404
+ prop.quaternionValue = new Quaternion(
405
+ Convert.ToSingle(qArr[0]),
406
+ Convert.ToSingle(qArr[1]),
407
+ Convert.ToSingle(qArr[2]),
408
+ Convert.ToSingle(qArr[3]));
409
+ break;
410
+ case SerializedPropertyType.Rect:
411
+ var rDict = value as Dictionary<string, object>;
412
+ if (rDict != null)
413
+ prop.rectValue = new Rect(
414
+ Convert.ToSingle(rDict["x"]),
415
+ Convert.ToSingle(rDict["y"]),
416
+ Convert.ToSingle(rDict["width"]),
417
+ Convert.ToSingle(rDict["height"]));
418
+ break;
419
+ case SerializedPropertyType.Bounds:
420
+ var bDict = value as Dictionary<string, object>;
421
+ if (bDict != null)
422
+ {
423
+ var center = bDict["center"] as List<object>;
424
+ var size = bDict["size"] as List<object>;
425
+ if (center != null && size != null)
426
+ prop.boundsValue = new Bounds(
427
+ new Vector3(Convert.ToSingle(center[0]), Convert.ToSingle(center[1]), Convert.ToSingle(center[2])),
428
+ new Vector3(Convert.ToSingle(size[0]), Convert.ToSingle(size[1]), Convert.ToSingle(size[2])));
429
+ }
430
+ break;
431
+ case SerializedPropertyType.ObjectReference:
432
+ prop.objectReferenceValue = ObjectReferenceResolver.Resolve(value, prop.displayName);
433
+ if (value != null && prop.objectReferenceValue == null)
434
+ throw new ArgumentException($"Unable to assign object reference to '{prop.displayName}'");
435
+ break;
436
+ case SerializedPropertyType.LayerMask:
437
+ prop.intValue = Convert.ToInt32(value);
438
+ break;
439
+ default:
440
+ throw new ArgumentException($"Cannot set property of type {prop.propertyType}");
441
+ }
442
+ }
443
+
444
+ private static void SetSerializedArrayValue(SerializedProperty prop, object value)
445
+ {
446
+ if (!(value is IList items))
447
+ throw new ArgumentException($"Property '{prop.displayName}' expects an array value");
448
+
449
+ prop.arraySize = items.Count;
450
+ for (var index = 0; index < items.Count; index++)
451
+ {
452
+ var element = prop.GetArrayElementAtIndex(index);
453
+ SetSerializedPropertyValue(element, items[index]);
454
+ }
455
+ }
456
+
457
+ private static object ConvertToJson(object value)
458
+ {
459
+ if (value == null) return null;
460
+ if (value is int || value is long || value is float || value is double ||
461
+ value is bool || value is string)
462
+ return value;
463
+ if (value is Vector2 v2)
464
+ return new List<object> { (double)v2.x, (double)v2.y };
465
+ if (value is Vector3 v3)
466
+ return new List<object> { (double)v3.x, (double)v3.y, (double)v3.z };
467
+ if (value is Vector4 v4)
468
+ return new List<object> { (double)v4.x, (double)v4.y, (double)v4.z, (double)v4.w };
469
+ if (value is Quaternion q)
470
+ return new List<object> { (double)q.x, (double)q.y, (double)q.z, (double)q.w };
471
+ if (value is Color c)
472
+ return new List<object> { (double)c.r, (double)c.g, (double)c.b, (double)c.a };
473
+ if (value is UnityEngine.Object uObj)
474
+ return ObjectReferenceResolver.Serialize(uObj);
475
+ return value.ToString();
476
+ }
477
+
478
+ private static object ConvertFromJson(object jsonValue, Type targetType)
479
+ {
480
+ if (jsonValue == null) return null;
481
+ if (targetType == typeof(int)) return Convert.ToInt32(jsonValue);
482
+ if (targetType == typeof(float)) return Convert.ToSingle(jsonValue);
483
+ if (targetType == typeof(double)) return Convert.ToDouble(jsonValue);
484
+ if (targetType == typeof(bool)) return Convert.ToBoolean(jsonValue);
485
+ if (targetType == typeof(string)) return jsonValue.ToString();
486
+ if (targetType == typeof(long)) return Convert.ToInt64(jsonValue);
487
+
488
+ if (targetType == typeof(Vector2) && jsonValue is List<object> v2)
489
+ return new Vector2(Convert.ToSingle(v2[0]), Convert.ToSingle(v2[1]));
490
+ if (targetType == typeof(Vector3) && jsonValue is List<object> v3)
491
+ return new Vector3(Convert.ToSingle(v3[0]), Convert.ToSingle(v3[1]), Convert.ToSingle(v3[2]));
492
+ if (targetType == typeof(Vector4) && jsonValue is List<object> v4)
493
+ return new Vector4(Convert.ToSingle(v4[0]), Convert.ToSingle(v4[1]), Convert.ToSingle(v4[2]), Convert.ToSingle(v4[3]));
494
+ if (targetType == typeof(Quaternion) && jsonValue is List<object> qv)
495
+ return new Quaternion(Convert.ToSingle(qv[0]), Convert.ToSingle(qv[1]), Convert.ToSingle(qv[2]), Convert.ToSingle(qv[3]));
496
+ if (targetType == typeof(Color) && jsonValue is List<object> cv)
497
+ return new Color(Convert.ToSingle(cv[0]), Convert.ToSingle(cv[1]), Convert.ToSingle(cv[2]),
498
+ cv.Count >= 4 ? Convert.ToSingle(cv[3]) : 1f);
499
+
500
+ return Convert.ChangeType(jsonValue, targetType);
501
+ }
502
+
503
+ private static GameObject FindGameObject(int instanceId)
504
+ {
505
+ var obj = EditorUtility.EntityIdToObject(instanceId) as GameObject;
506
+ if (obj != null) return obj;
507
+
508
+ // Search in loaded scenes
509
+ for (int i = 0; i < SceneManager.sceneCount; i++)
510
+ {
511
+ var scene = SceneManager.GetSceneAt(i);
512
+ if (!scene.isLoaded) continue;
513
+ foreach (var root in scene.GetRootGameObjects())
514
+ {
515
+ var found = FindInHierarchy(root, instanceId);
516
+ if (found != null) return found;
517
+ }
518
+ }
519
+
520
+ throw new ArgumentException($"GameObject not found: {instanceId}");
521
+ }
522
+
523
+ private static GameObject FindInHierarchy(GameObject go, int instanceId)
524
+ {
525
+ if (go.GetInstanceID() == instanceId) return go;
526
+ for (int i = 0; i < go.transform.childCount; i++)
527
+ {
528
+ var found = FindInHierarchy(go.transform.GetChild(i).gameObject, instanceId);
529
+ if (found != null) return found;
530
+ }
531
+ return null;
532
+ }
533
+
534
+ private static Component FindComponent(GameObject go, string typeName)
535
+ {
536
+ foreach (var c in go.GetComponents<Component>())
537
+ {
538
+ if (c == null) continue;
539
+ if (c.GetType().Name == typeName || c.GetType().FullName == typeName)
540
+ return c;
541
+ }
542
+ throw new ArgumentException($"Component '{typeName}' not found on '{go.name}'");
543
+ }
544
+
545
+ // Extension-like helper for SerializedProperty.isReadOnly
546
+ // which doesn't exist as a public API in older Unity
547
+ }
548
+
549
+ internal static class SerializedPropertyExtensions
550
+ {
551
+ internal static bool isReadOnly(this SerializedProperty prop, bool includeChildren)
552
+ {
553
+ // Check if the property path suggests it's a built-in non-editable field
554
+ string path = prop.propertyPath;
555
+ if (path == "m_Script") return true;
556
+ if (path == "m_ObjectHideFlags") return true;
557
+ return false;
558
+ }
559
+ }
560
+ }
561
+
562
+
563
+
@@ -0,0 +1,2 @@
1
+ fileFormatVersion: 2
2
+ guid: 8d9194b68ed2905498f060fb468875c4