using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEngine; using Newtonsoft.Json; namespace SynapticPro { /// /// Dynamic Meta-Tools for NexusUnityExecutor /// Provides reflection-based inspection and modification of Unity components /// public partial class NexusUnityExecutor { #region Dynamic Meta-Tools /// /// Dynamically inspect any Unity object, component, scene, or project assets /// private string DynamicInspect(Dictionary parameters) { try { var target = parameters.GetValueOrDefault("target", "gameobject").ToLower(); var name = parameters.GetValueOrDefault("name", ""); var componentType = parameters.GetValueOrDefault("component", ""); var path = parameters.GetValueOrDefault("path", ""); int.TryParse(parameters.GetValueOrDefault("depth", "2"), out int depth); switch (target) { case "gameobject": return InspectGameObject(name, depth); case "component": return InspectComponent(name, componentType, depth); case "scene": return InspectScene(); case "hierarchy": return InspectHierarchy(depth); case "prefabs": return InspectPrefabs(path); case "project": return InspectProject(path); default: return JsonConvert.SerializeObject(new { error = $"Unknown inspect target: {target}" }); } } catch (Exception e) { return CreateErrorResponse("DynamicInspect", e, parameters); } } private string InspectGameObject(string name, int depth) { if (string.IsNullOrEmpty(name)) { // List all root GameObjects var rootObjects = UnityEngine.SceneManagement.SceneManager.GetActiveScene() .GetRootGameObjects() .Select(go => new { name = go.name, active = go.activeSelf, components = go.GetComponents().Select(c => c?.GetType().Name).Where(n => n != null).ToList(), childCount = go.transform.childCount }).ToList(); return JsonConvert.SerializeObject(new { success = true, message = $"Found {rootObjects.Count} root GameObjects", gameObjects = rootObjects }); } var gameObject = GameObject.Find(name); if (gameObject == null) { gameObject = FindGameObjectByPathDynamic(name); } if (gameObject == null) { return JsonConvert.SerializeObject(new { error = $"GameObject '{name}' not found" }); } var components = new List(); foreach (var comp in gameObject.GetComponents()) { if (comp == null) continue; components.Add(new { type = comp.GetType().Name, fullType = comp.GetType().FullName, enabled = (comp is Behaviour b) ? b.enabled : true }); } var children = new List(); if (depth > 0) { foreach (Transform child in gameObject.transform) { children.Add(new { name = child.name, active = child.gameObject.activeSelf, componentCount = child.GetComponents().Length, childCount = child.childCount }); } } return JsonConvert.SerializeObject(new { success = true, gameObject = new { name = gameObject.name, active = gameObject.activeSelf, layer = LayerMask.LayerToName(gameObject.layer), tag = gameObject.tag, isStatic = gameObject.isStatic, transform = new { position = new { x = gameObject.transform.position.x, y = gameObject.transform.position.y, z = gameObject.transform.position.z }, rotation = new { x = gameObject.transform.eulerAngles.x, y = gameObject.transform.eulerAngles.y, z = gameObject.transform.eulerAngles.z }, scale = new { x = gameObject.transform.localScale.x, y = gameObject.transform.localScale.y, z = gameObject.transform.localScale.z } }, components = components, children = children } }); } private string InspectComponent(string gameObjectName, string componentType, int depth) { if (string.IsNullOrEmpty(gameObjectName)) { return JsonConvert.SerializeObject(new { error = "GameObject name required" }); } var gameObject = GameObject.Find(gameObjectName) ?? FindGameObjectByPathDynamic(gameObjectName); if (gameObject == null) { return JsonConvert.SerializeObject(new { error = $"GameObject '{gameObjectName}' not found" }); } Component component = null; if (!string.IsNullOrEmpty(componentType)) { component = gameObject.GetComponents() .FirstOrDefault(c => c != null && (c.GetType().Name.Equals(componentType, StringComparison.OrdinalIgnoreCase) || c.GetType().Name.EndsWith(componentType, StringComparison.OrdinalIgnoreCase))); } if (component == null && !string.IsNullOrEmpty(componentType)) { return JsonConvert.SerializeObject(new { error = $"Component '{componentType}' not found on '{gameObjectName}'", availableComponents = gameObject.GetComponents() .Where(c => c != null) .Select(c => c.GetType().Name) .ToList() }); } // If no specific component, list all with their properties if (component == null) { var allComponents = new List(); foreach (var comp in gameObject.GetComponents()) { if (comp == null) continue; allComponents.Add(new { type = comp.GetType().Name, properties = GetSerializedPropertiesDynamic(comp, depth) }); } return JsonConvert.SerializeObject(new { success = true, gameObject = gameObjectName, components = allComponents }); } // Inspect specific component var properties = GetSerializedPropertiesDynamic(component, depth); return JsonConvert.SerializeObject(new { success = true, gameObject = gameObjectName, component = componentType, type = component.GetType().FullName, properties = properties }); } private List GetSerializedPropertiesDynamic(Component component, int depth) { var properties = new List(); var so = new SerializedObject(component); var iterator = so.GetIterator(); bool enterChildren = true; while (iterator.NextVisible(enterChildren)) { if (iterator.depth > depth) { enterChildren = false; continue; } enterChildren = true; var propInfo = new Dictionary { ["path"] = iterator.propertyPath, ["name"] = iterator.name, ["type"] = iterator.propertyType.ToString(), ["editable"] = iterator.editable }; // Get value based on type switch (iterator.propertyType) { case SerializedPropertyType.Integer: propInfo["value"] = iterator.intValue; break; case SerializedPropertyType.Float: propInfo["value"] = iterator.floatValue; break; case SerializedPropertyType.Boolean: propInfo["value"] = iterator.boolValue; break; case SerializedPropertyType.String: propInfo["value"] = iterator.stringValue; break; case SerializedPropertyType.Enum: propInfo["value"] = iterator.enumDisplayNames?.Length > iterator.enumValueIndex && iterator.enumValueIndex >= 0 ? iterator.enumDisplayNames[iterator.enumValueIndex] : iterator.enumValueIndex.ToString(); propInfo["options"] = iterator.enumDisplayNames; break; case SerializedPropertyType.Vector2: propInfo["value"] = new { x = iterator.vector2Value.x, y = iterator.vector2Value.y }; break; case SerializedPropertyType.Vector3: propInfo["value"] = new { x = iterator.vector3Value.x, y = iterator.vector3Value.y, z = iterator.vector3Value.z }; break; case SerializedPropertyType.Vector4: propInfo["value"] = new { x = iterator.vector4Value.x, y = iterator.vector4Value.y, z = iterator.vector4Value.z, w = iterator.vector4Value.w }; break; case SerializedPropertyType.Color: propInfo["value"] = new { r = iterator.colorValue.r, g = iterator.colorValue.g, b = iterator.colorValue.b, a = iterator.colorValue.a }; break; case SerializedPropertyType.ObjectReference: propInfo["value"] = iterator.objectReferenceValue?.name ?? "null"; propInfo["objectType"] = iterator.objectReferenceValue?.GetType().Name ?? "null"; break; case SerializedPropertyType.LayerMask: propInfo["value"] = iterator.intValue; break; case SerializedPropertyType.Rect: var rect = iterator.rectValue; propInfo["value"] = new { x = rect.x, y = rect.y, width = rect.width, height = rect.height }; break; case SerializedPropertyType.ArraySize: propInfo["value"] = iterator.intValue; break; case SerializedPropertyType.AnimationCurve: propInfo["value"] = $"AnimationCurve with {iterator.animationCurveValue?.keys?.Length ?? 0} keys"; break; default: propInfo["value"] = "(complex type)"; break; } properties.Add(propInfo); } return properties; } private string InspectScene() { var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); var rootObjects = scene.GetRootGameObjects(); int totalObjects = 0; int totalComponents = 0; var componentCounts = new Dictionary(); void CountRecursive(GameObject go) { totalObjects++; foreach (var comp in go.GetComponents()) { if (comp == null) continue; totalComponents++; var typeName = comp.GetType().Name; componentCounts[typeName] = componentCounts.GetValueOrDefault(typeName, 0) + 1; } foreach (Transform child in go.transform) { CountRecursive(child.gameObject); } } foreach (var root in rootObjects) { CountRecursive(root); } return JsonConvert.SerializeObject(new { success = true, scene = new { name = scene.name, path = scene.path, isDirty = scene.isDirty, rootCount = rootObjects.Length, totalGameObjects = totalObjects, totalComponents = totalComponents, topComponents = componentCounts .OrderByDescending(x => x.Value) .Take(20) .Select(x => new { type = x.Key, count = x.Value }) .ToList() } }); } private string InspectHierarchy(int depth) { var scene = UnityEngine.SceneManagement.SceneManager.GetActiveScene(); var rootObjects = scene.GetRootGameObjects(); object BuildHierarchy(GameObject go, int currentDepth) { var children = new List(); if (currentDepth < depth) { foreach (Transform child in go.transform) { children.Add(BuildHierarchy(child.gameObject, currentDepth + 1)); } } return new { name = go.name, active = go.activeSelf, components = go.GetComponents() .Where(c => c != null) .Select(c => c.GetType().Name) .ToList(), children = children.Count > 0 ? children : null }; } var hierarchy = rootObjects.Select(go => BuildHierarchy(go, 0)).ToList(); return JsonConvert.SerializeObject(new { success = true, scene = scene.name, depth = depth, hierarchy = hierarchy }); } private string InspectPrefabs(string pathFilter) { try { var searchPath = string.IsNullOrEmpty(pathFilter) ? "Assets" : pathFilter.Replace("*", ""); if (searchPath.EndsWith("/")) searchPath = searchPath.TrimEnd('/'); if (!searchPath.StartsWith("Assets")) searchPath = "Assets"; var guids = AssetDatabase.FindAssets("t:Prefab", new[] { searchPath }); var prefabs = guids .Select(guid => AssetDatabase.GUIDToAssetPath(guid)) .Where(p => string.IsNullOrEmpty(pathFilter) || MatchesWildcardDynamic(p, pathFilter)) .Take(100) .Select(p => { var prefab = AssetDatabase.LoadAssetAtPath(p); return new { path = p, name = prefab?.name ?? Path.GetFileNameWithoutExtension(p), components = prefab?.GetComponents() .Where(c => c != null) .Select(c => c.GetType().Name) .ToList() ?? new List() }; }) .ToList(); return JsonConvert.SerializeObject(new { success = true, filter = pathFilter ?? "all", count = prefabs.Count, prefabs = prefabs }); } catch (Exception e) { return JsonConvert.SerializeObject(new { error = e.Message }); } } private string InspectProject(string pathFilter) { try { var searchPath = string.IsNullOrEmpty(pathFilter) ? "Assets" : pathFilter; if (!searchPath.StartsWith("Assets")) searchPath = "Assets/" + searchPath; searchPath = searchPath.TrimEnd('/'); // Get folder structure string[] folders = new string[0]; try { folders = AssetDatabase.GetSubFolders(searchPath); } catch { } // Get assets in current folder var guids = AssetDatabase.FindAssets("", new[] { searchPath }); var assets = guids .Select(guid => AssetDatabase.GUIDToAssetPath(guid)) .Where(p => Path.GetDirectoryName(p).Replace("\\", "/") == searchPath) .Take(50) .Select(p => new { path = p, name = Path.GetFileName(p), type = AssetDatabase.GetMainAssetTypeAtPath(p)?.Name ?? "Unknown" }) .ToList(); return JsonConvert.SerializeObject(new { success = true, currentPath = searchPath, folders = folders, assets = assets }); } catch (Exception e) { return JsonConvert.SerializeObject(new { error = e.Message }); } } private bool MatchesWildcardDynamic(string path, string pattern) { if (string.IsNullOrEmpty(pattern)) return true; var regex = "^" + System.Text.RegularExpressions.Regex.Escape(pattern) .Replace("\\*\\*", ".*") .Replace("\\*", "[^/]*") .Replace("\\?", ".") + "$"; return System.Text.RegularExpressions.Regex.IsMatch(path, regex, System.Text.RegularExpressions.RegexOptions.IgnoreCase); } private GameObject FindGameObjectByPathDynamic(string path) { if (string.IsNullOrEmpty(path)) return null; var parts = path.Split('/'); GameObject current = null; foreach (var part in parts) { if (current == null) { current = GameObject.Find(part); if (current == null) { var roots = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects(); current = roots.FirstOrDefault(r => r.name == part); } } else { var child = current.transform.Find(part); current = child?.gameObject; } if (current == null) return null; } return current; } /// /// Dynamically modify any property of a Unity component /// private string DynamicModify(Dictionary parameters) { try { var gameObjectName = parameters.GetValueOrDefault("gameObject", ""); var componentType = parameters.GetValueOrDefault("component", ""); var propertiesJson = parameters.GetValueOrDefault("properties", "{}"); bool.TryParse(parameters.GetValueOrDefault("createIfMissing", "false"), out bool createIfMissing); if (string.IsNullOrEmpty(gameObjectName)) { return JsonConvert.SerializeObject(new { error = "GameObject name required" }); } var gameObject = GameObject.Find(gameObjectName) ?? FindGameObjectByPathDynamic(gameObjectName); if (gameObject == null) { return JsonConvert.SerializeObject(new { error = $"GameObject '{gameObjectName}' not found" }); } // Find or create component Component component = null; if (!string.IsNullOrEmpty(componentType)) { component = gameObject.GetComponents() .FirstOrDefault(c => c != null && (c.GetType().Name.Equals(componentType, StringComparison.OrdinalIgnoreCase) || c.GetType().Name.EndsWith(componentType, StringComparison.OrdinalIgnoreCase))); if (component == null && createIfMissing) { var type = FindComponentTypeDynamic(componentType); if (type != null) { component = gameObject.AddComponent(type); } } if (component == null) { return JsonConvert.SerializeObject(new { error = $"Component '{componentType}' not found on '{gameObjectName}'", hint = createIfMissing ? "Could not create component - type not found" : "Use createIfMissing:true to add it" }); } } else { return JsonConvert.SerializeObject(new { error = "Component type required" }); } // Parse properties var properties = JsonConvert.DeserializeObject>(propertiesJson); if (properties == null || properties.Count == 0) { return JsonConvert.SerializeObject(new { error = "No properties specified" }); } var so = new SerializedObject(component); var modifiedProperties = new List(); var failedProperties = new List(); foreach (var kvp in properties) { var prop = so.FindProperty(kvp.Key); if (prop == null) { failedProperties.Add(new { path = kvp.Key, error = "Property not found" }); continue; } if (!prop.editable) { failedProperties.Add(new { path = kvp.Key, error = "Property not editable" }); continue; } try { SetSerializedPropertyValueDynamic(prop, kvp.Value); modifiedProperties.Add(kvp.Key); } catch (Exception e) { failedProperties.Add(new { path = kvp.Key, error = e.Message }); } } so.ApplyModifiedProperties(); EditorUtility.SetDirty(gameObject); return JsonConvert.SerializeObject(new { success = true, gameObject = gameObjectName, component = componentType, modifiedProperties = modifiedProperties, failedProperties = failedProperties.Count > 0 ? failedProperties : null }); } catch (Exception e) { return CreateErrorResponse("DynamicModify", e, parameters); } } private void SetSerializedPropertyValueDynamic(SerializedProperty prop, object value) { switch (prop.propertyType) { case SerializedPropertyType.Integer: prop.intValue = Convert.ToInt32(value); break; case SerializedPropertyType.Float: prop.floatValue = Convert.ToSingle(value); break; case SerializedPropertyType.Boolean: prop.boolValue = Convert.ToBoolean(value); break; case SerializedPropertyType.String: prop.stringValue = value?.ToString() ?? ""; break; case SerializedPropertyType.Enum: if (value is int intVal) prop.enumValueIndex = intVal; else if (value is long longVal) prop.enumValueIndex = (int)longVal; else if (value is string strVal) { var idx = Array.IndexOf(prop.enumDisplayNames, strVal); if (idx >= 0) prop.enumValueIndex = idx; else if (int.TryParse(strVal, out int parsed)) prop.enumValueIndex = parsed; } break; case SerializedPropertyType.Vector2: if (value is Newtonsoft.Json.Linq.JObject v2) prop.vector2Value = new Vector2(v2["x"]?.ToObject() ?? 0, v2["y"]?.ToObject() ?? 0); break; case SerializedPropertyType.Vector3: if (value is Newtonsoft.Json.Linq.JObject v3) prop.vector3Value = new Vector3(v3["x"]?.ToObject() ?? 0, v3["y"]?.ToObject() ?? 0, v3["z"]?.ToObject() ?? 0); break; case SerializedPropertyType.Vector4: if (value is Newtonsoft.Json.Linq.JObject v4) prop.vector4Value = new Vector4(v4["x"]?.ToObject() ?? 0, v4["y"]?.ToObject() ?? 0, v4["z"]?.ToObject() ?? 0, v4["w"]?.ToObject() ?? 0); break; case SerializedPropertyType.Color: if (value is Newtonsoft.Json.Linq.JObject c) prop.colorValue = new Color(c["r"]?.ToObject() ?? 1, c["g"]?.ToObject() ?? 1, c["b"]?.ToObject() ?? 1, c["a"]?.ToObject() ?? 1); else if (value is string hex) prop.colorValue = ParseHexColorDynamic(hex); break; case SerializedPropertyType.LayerMask: prop.intValue = Convert.ToInt32(value); break; default: throw new NotSupportedException($"Property type {prop.propertyType} not supported for direct modification"); } } private Color ParseHexColorDynamic(string hex) { if (string.IsNullOrEmpty(hex)) return Color.white; hex = hex.TrimStart('#'); if (hex.Length == 6) { byte r = Convert.ToByte(hex.Substring(0, 2), 16); byte g = Convert.ToByte(hex.Substring(2, 2), 16); byte b = Convert.ToByte(hex.Substring(4, 2), 16); return new Color32(r, g, b, 255); } return Color.white; } private Type FindComponentTypeDynamic(string typeName) { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { try { var type = assembly.GetTypes() .FirstOrDefault(t => typeof(Component).IsAssignableFrom(t) && (t.Name.Equals(typeName, StringComparison.OrdinalIgnoreCase) || t.Name.EndsWith(typeName, StringComparison.OrdinalIgnoreCase))); if (type != null) return type; } catch { } } return null; } /// /// Universal creation tool for GameObjects, prefabs, scenes, and components /// private string DynamicCreate(Dictionary parameters) { try { var createType = parameters.GetValueOrDefault("type", "gameobject").ToLower(); switch (createType) { case "gameobject": return CreateDynamicGameObject(parameters); case "prefab": return CreateDynamicPrefabInstance(parameters); case "scene": return LoadDynamicScene(parameters); case "component": return AddDynamicComponent(parameters); default: return JsonConvert.SerializeObject(new { error = $"Unknown create type: {createType}" }); } } catch (Exception e) { return CreateErrorResponse("DynamicCreate", e, parameters); } } private string CreateDynamicGameObject(Dictionary parameters) { var name = parameters.GetValueOrDefault("name", "New GameObject"); var primitive = parameters.GetValueOrDefault("primitive", "empty").ToLower(); var parentName = parameters.GetValueOrDefault("parent", ""); GameObject go; switch (primitive) { case "cube": go = GameObject.CreatePrimitive(PrimitiveType.Cube); break; case "sphere": go = GameObject.CreatePrimitive(PrimitiveType.Sphere); break; case "cylinder": go = GameObject.CreatePrimitive(PrimitiveType.Cylinder); break; case "plane": go = GameObject.CreatePrimitive(PrimitiveType.Plane); break; case "capsule": go = GameObject.CreatePrimitive(PrimitiveType.Capsule); break; case "quad": go = GameObject.CreatePrimitive(PrimitiveType.Quad); break; default: go = new GameObject(); break; } go.name = name; if (!string.IsNullOrEmpty(parentName)) { var parent = GameObject.Find(parentName) ?? FindGameObjectByPathDynamic(parentName); if (parent != null) { go.transform.SetParent(parent.transform, false); } } ApplyTransformFromParametersDynamic(go, parameters); Undo.RegisterCreatedObjectUndo(go, $"Create {name}"); Selection.activeGameObject = go; return JsonConvert.SerializeObject(new { success = true, message = $"Created GameObject '{name}'", gameObject = new { name = go.name, primitive = primitive, path = GetGameObjectPathDynamic(go) } }); } private string CreateDynamicPrefabInstance(Dictionary parameters) { var assetPath = parameters.GetValueOrDefault("asset", ""); var instanceName = parameters.GetValueOrDefault("name", ""); var parentName = parameters.GetValueOrDefault("parent", ""); if (string.IsNullOrEmpty(assetPath)) { return JsonConvert.SerializeObject(new { error = "Asset path required" }); } var prefab = AssetDatabase.LoadAssetAtPath(assetPath); if (prefab == null) { var guids = AssetDatabase.FindAssets($"{Path.GetFileNameWithoutExtension(assetPath)} t:Prefab"); if (guids.Length > 0) { var foundPath = AssetDatabase.GUIDToAssetPath(guids[0]); prefab = AssetDatabase.LoadAssetAtPath(foundPath); } } if (prefab == null) { return JsonConvert.SerializeObject(new { error = $"Prefab not found at '{assetPath}'" }); } var instance = (GameObject)PrefabUtility.InstantiatePrefab(prefab); if (!string.IsNullOrEmpty(instanceName)) { instance.name = instanceName; } if (!string.IsNullOrEmpty(parentName)) { var parent = GameObject.Find(parentName) ?? FindGameObjectByPathDynamic(parentName); if (parent != null) { instance.transform.SetParent(parent.transform, false); } } ApplyTransformFromParametersDynamic(instance, parameters); Undo.RegisterCreatedObjectUndo(instance, $"Instantiate {prefab.name}"); Selection.activeGameObject = instance; return JsonConvert.SerializeObject(new { success = true, message = $"Instantiated prefab '{prefab.name}'", instance = new { name = instance.name, prefabPath = assetPath, path = GetGameObjectPathDynamic(instance) } }); } private string LoadDynamicScene(Dictionary parameters) { var sceneName = parameters.GetValueOrDefault("scene", ""); bool.TryParse(parameters.GetValueOrDefault("additive", "false"), out bool additive); if (string.IsNullOrEmpty(sceneName)) { return JsonConvert.SerializeObject(new { error = "Scene name required" }); } string scenePath = sceneName; if (!sceneName.EndsWith(".unity")) { var guids = AssetDatabase.FindAssets($"{sceneName} t:Scene"); if (guids.Length > 0) { scenePath = AssetDatabase.GUIDToAssetPath(guids[0]); } else { foreach (var buildScene in EditorBuildSettings.scenes) { if (Path.GetFileNameWithoutExtension(buildScene.path).Equals(sceneName, StringComparison.OrdinalIgnoreCase)) { scenePath = buildScene.path; break; } } } } if (!File.Exists(scenePath)) { return JsonConvert.SerializeObject(new { error = $"Scene '{sceneName}' not found" }); } var mode = additive ? UnityEditor.SceneManagement.OpenSceneMode.Additive : UnityEditor.SceneManagement.OpenSceneMode.Single; var scene = UnityEditor.SceneManagement.EditorSceneManager.OpenScene(scenePath, mode); return JsonConvert.SerializeObject(new { success = true, message = $"Loaded scene '{scene.name}' {(additive ? "additively" : "")}", scene = new { name = scene.name, path = scene.path, rootCount = scene.rootCount } }); } private string AddDynamicComponent(Dictionary parameters) { var gameObjectName = parameters.GetValueOrDefault("gameObject", ""); var componentType = parameters.GetValueOrDefault("component", ""); if (string.IsNullOrEmpty(gameObjectName)) { return JsonConvert.SerializeObject(new { error = "GameObject name required" }); } if (string.IsNullOrEmpty(componentType)) { return JsonConvert.SerializeObject(new { error = "Component type required" }); } var gameObject = GameObject.Find(gameObjectName) ?? FindGameObjectByPathDynamic(gameObjectName); if (gameObject == null) { return JsonConvert.SerializeObject(new { error = $"GameObject '{gameObjectName}' not found" }); } var type = FindComponentTypeDynamic(componentType); if (type == null) { return JsonConvert.SerializeObject(new { error = $"Component type '{componentType}' not found" }); } if (gameObject.GetComponent(type) != null) { return JsonConvert.SerializeObject(new { success = true, message = $"Component '{componentType}' already exists on '{gameObjectName}'", alreadyExists = true }); } var component = Undo.AddComponent(gameObject, type); return JsonConvert.SerializeObject(new { success = true, message = $"Added component '{type.Name}' to '{gameObjectName}'", component = new { type = type.Name, fullType = type.FullName } }); } private void ApplyTransformFromParametersDynamic(GameObject go, Dictionary parameters) { if (parameters.TryGetValue("position", out var posJson)) { try { var pos = JsonConvert.DeserializeObject>(posJson); if (pos != null) { go.transform.position = new Vector3( pos.GetValueOrDefault("x", 0), pos.GetValueOrDefault("y", 0), pos.GetValueOrDefault("z", 0) ); } } catch { } } if (parameters.TryGetValue("rotation", out var rotJson)) { try { var rot = JsonConvert.DeserializeObject>(rotJson); if (rot != null) { go.transform.eulerAngles = new Vector3( rot.GetValueOrDefault("x", 0), rot.GetValueOrDefault("y", 0), rot.GetValueOrDefault("z", 0) ); } } catch { } } if (parameters.TryGetValue("scale", out var scaleJson)) { try { var scale = JsonConvert.DeserializeObject>(scaleJson); if (scale != null) { go.transform.localScale = new Vector3( scale.GetValueOrDefault("x", 1), scale.GetValueOrDefault("y", 1), scale.GetValueOrDefault("z", 1) ); } } catch { } } } private string GetGameObjectPathDynamic(GameObject go) { string path = go.name; Transform current = go.transform.parent; while (current != null) { path = current.name + "/" + path; current = current.parent; } return path; } #endregion } }