diff --git a/UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef b/UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef new file mode 100644 index 0000000..b006d0a --- /dev/null +++ b/UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef @@ -0,0 +1,19 @@ +{ + "name": "UnityMcpBridge.Editor", + "rootNamespace": "UnityMcpBridge.Editor", + "references": [ + "UnityMcpBridge.Runtime", + "GUID:560b04d1a97f54a46a2660c3cc343a6f" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef.meta b/UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef.meta new file mode 100644 index 0000000..7f200d1 --- /dev/null +++ b/UnityMcpBridge/Editor/UnityMcpBridge.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 04b0581466993404a8fae14802c2a5a6 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityMcpBridge/Runtime.meta b/UnityMcpBridge/Runtime.meta new file mode 100644 index 0000000..ae1e4df --- /dev/null +++ b/UnityMcpBridge/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b5cc10fd969474b3680332e542416860 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityMcpBridge/Runtime/Serialization.meta b/UnityMcpBridge/Runtime/Serialization.meta new file mode 100644 index 0000000..89cd67a --- /dev/null +++ b/UnityMcpBridge/Runtime/Serialization.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c7e33d6224fe6473f9bc69fe6d40e508 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs b/UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs new file mode 100644 index 0000000..ad8f150 --- /dev/null +++ b/UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs @@ -0,0 +1,266 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using UnityEngine; +#if UNITY_EDITOR +using UnityEditor; // Required for AssetDatabase and EditorUtility +#endif + +namespace UnityMcpBridge.Runtime.Serialization +{ + public class Vector3Converter : JsonConverter + { + public override void WriteJson(JsonWriter writer, Vector3 value, JsonSerializer serializer) + { + writer.WriteStartObject(); + writer.WritePropertyName("x"); + writer.WriteValue(value.x); + writer.WritePropertyName("y"); + writer.WriteValue(value.y); + writer.WritePropertyName("z"); + writer.WriteValue(value.z); + writer.WriteEndObject(); + } + + public override Vector3 ReadJson(JsonReader reader, Type objectType, Vector3 existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jo = JObject.Load(reader); + return new Vector3( + (float)jo["x"], + (float)jo["y"], + (float)jo["z"] + ); + } + } + + public class Vector2Converter : JsonConverter + { + public override void WriteJson(JsonWriter writer, Vector2 value, JsonSerializer serializer) + { + writer.WriteStartObject(); + writer.WritePropertyName("x"); + writer.WriteValue(value.x); + writer.WritePropertyName("y"); + writer.WriteValue(value.y); + writer.WriteEndObject(); + } + + public override Vector2 ReadJson(JsonReader reader, Type objectType, Vector2 existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jo = JObject.Load(reader); + return new Vector2( + (float)jo["x"], + (float)jo["y"] + ); + } + } + + public class QuaternionConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, Quaternion value, JsonSerializer serializer) + { + writer.WriteStartObject(); + writer.WritePropertyName("x"); + writer.WriteValue(value.x); + writer.WritePropertyName("y"); + writer.WriteValue(value.y); + writer.WritePropertyName("z"); + writer.WriteValue(value.z); + writer.WritePropertyName("w"); + writer.WriteValue(value.w); + writer.WriteEndObject(); + } + + public override Quaternion ReadJson(JsonReader reader, Type objectType, Quaternion existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jo = JObject.Load(reader); + return new Quaternion( + (float)jo["x"], + (float)jo["y"], + (float)jo["z"], + (float)jo["w"] + ); + } + } + + public class ColorConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, Color value, JsonSerializer serializer) + { + writer.WriteStartObject(); + writer.WritePropertyName("r"); + writer.WriteValue(value.r); + writer.WritePropertyName("g"); + writer.WriteValue(value.g); + writer.WritePropertyName("b"); + writer.WriteValue(value.b); + writer.WritePropertyName("a"); + writer.WriteValue(value.a); + writer.WriteEndObject(); + } + + public override Color ReadJson(JsonReader reader, Type objectType, Color existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jo = JObject.Load(reader); + return new Color( + (float)jo["r"], + (float)jo["g"], + (float)jo["b"], + (float)jo["a"] + ); + } + } + + public class RectConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, Rect value, JsonSerializer serializer) + { + writer.WriteStartObject(); + writer.WritePropertyName("x"); + writer.WriteValue(value.x); + writer.WritePropertyName("y"); + writer.WriteValue(value.y); + writer.WritePropertyName("width"); + writer.WriteValue(value.width); + writer.WritePropertyName("height"); + writer.WriteValue(value.height); + writer.WriteEndObject(); + } + + public override Rect ReadJson(JsonReader reader, Type objectType, Rect existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jo = JObject.Load(reader); + return new Rect( + (float)jo["x"], + (float)jo["y"], + (float)jo["width"], + (float)jo["height"] + ); + } + } + + public class BoundsConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, Bounds value, JsonSerializer serializer) + { + writer.WriteStartObject(); + writer.WritePropertyName("center"); + serializer.Serialize(writer, value.center); // Use serializer to handle nested Vector3 + writer.WritePropertyName("size"); + serializer.Serialize(writer, value.size); // Use serializer to handle nested Vector3 + writer.WriteEndObject(); + } + + public override Bounds ReadJson(JsonReader reader, Type objectType, Bounds existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jo = JObject.Load(reader); + Vector3 center = jo["center"].ToObject(serializer); // Use serializer to handle nested Vector3 + Vector3 size = jo["size"].ToObject(serializer); // Use serializer to handle nested Vector3 + return new Bounds(center, size); + } + } + + // Converter for UnityEngine.Object references (GameObjects, Components, Materials, Textures, etc.) + public class UnityEngineObjectConverter : JsonConverter + { + public override bool CanRead => true; // We need to implement ReadJson + public override bool CanWrite => true; + + public override void WriteJson(JsonWriter writer, UnityEngine.Object value, JsonSerializer serializer) + { + if (value == null) + { + writer.WriteNull(); + return; + } + +#if UNITY_EDITOR // AssetDatabase and EditorUtility are Editor-only + if (UnityEditor.AssetDatabase.Contains(value)) + { + // It's an asset (Material, Texture, Prefab, etc.) + string path = UnityEditor.AssetDatabase.GetAssetPath(value); + if (!string.IsNullOrEmpty(path)) + { + writer.WriteValue(path); + } + else + { + // Asset exists but path couldn't be found? Write minimal info. + writer.WriteStartObject(); + writer.WritePropertyName("name"); + writer.WriteValue(value.name); + writer.WritePropertyName("instanceID"); + writer.WriteValue(value.GetInstanceID()); + writer.WritePropertyName("isAssetWithoutPath"); + writer.WriteValue(true); + writer.WriteEndObject(); + } + } + else + { + // It's a scene object (GameObject, Component, etc.) + writer.WriteStartObject(); + writer.WritePropertyName("name"); + writer.WriteValue(value.name); + writer.WritePropertyName("instanceID"); + writer.WriteValue(value.GetInstanceID()); + writer.WriteEndObject(); + } +#else + // Runtime fallback: Write basic info without AssetDatabase + writer.WriteStartObject(); + writer.WritePropertyName("name"); + writer.WriteValue(value.name); + writer.WritePropertyName("instanceID"); + writer.WriteValue(value.GetInstanceID()); + writer.WritePropertyName("warning"); + writer.WriteValue("UnityEngineObjectConverter running in non-Editor mode, asset path unavailable."); + writer.WriteEndObject(); +#endif + } + + public override UnityEngine.Object ReadJson(JsonReader reader, Type objectType, UnityEngine.Object existingValue, bool hasExistingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + { + return null; + } + +#if UNITY_EDITOR + if (reader.TokenType == JsonToken.String) + { + // Assume it's an asset path + string path = reader.Value.ToString(); + return UnityEditor.AssetDatabase.LoadAssetAtPath(path, objectType); + } + + if (reader.TokenType == JsonToken.StartObject) + { + JObject jo = JObject.Load(reader); + if (jo.TryGetValue("instanceID", out JToken idToken) && idToken.Type == JTokenType.Integer) + { + int instanceId = idToken.ToObject(); + UnityEngine.Object obj = UnityEditor.EditorUtility.InstanceIDToObject(instanceId); + if (obj != null && objectType.IsAssignableFrom(obj.GetType())) + { + return obj; + } + } + // Could potentially try finding by name as a fallback if ID lookup fails/isn't present + // but that's less reliable. + } +#else + // Runtime deserialization is tricky without AssetDatabase/EditorUtility + // Maybe log a warning and return null or existingValue? + Debug.LogWarning("UnityEngineObjectConverter cannot deserialize complex objects in non-Editor mode."); + // Skip the token to avoid breaking the reader + if (reader.TokenType == JsonToken.StartObject) JObject.Load(reader); + else if (reader.TokenType == JsonToken.String) reader.ReadAsString(); + // Return null or existing value, depending on desired behavior + return existingValue; +#endif + + throw new JsonSerializationException($"Unexpected token type '{reader.TokenType}' when deserializing UnityEngine.Object"); + } + } +} \ No newline at end of file diff --git a/UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs.meta b/UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs.meta new file mode 100644 index 0000000..9596160 --- /dev/null +++ b/UnityMcpBridge/Runtime/Serialization/UnityTypeConverters.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e65311c160f0d41d4a1b45a3dba8dd5a \ No newline at end of file diff --git a/UnityMcpBridge/Runtime/UnityMcpBridge.Runtime.asmdef b/UnityMcpBridge/Runtime/UnityMcpBridge.Runtime.asmdef new file mode 100644 index 0000000..3e8a8d9 --- /dev/null +++ b/UnityMcpBridge/Runtime/UnityMcpBridge.Runtime.asmdef @@ -0,0 +1,16 @@ +{ + "name": "UnityMcpBridge.Runtime", + "rootNamespace": "UnityMcpBridge.Runtime", + "references": [ + "GUID:560b04d1a97f54a46a2660c3cc343a6f" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/UnityMcpBridge/Runtime/UnityMcpBridge.Runtime.asmdef.meta b/UnityMcpBridge/Runtime/UnityMcpBridge.Runtime.asmdef.meta new file mode 100644 index 0000000..538a257 --- /dev/null +++ b/UnityMcpBridge/Runtime/UnityMcpBridge.Runtime.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7d76fa93cbc5144028727fd2dbac5655 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: