diff --git a/Runtime/GameplayTagJsonConverter.cs b/Runtime/GameplayTagJsonConverter.cs new file mode 100644 index 0000000..f98c165 --- /dev/null +++ b/Runtime/GameplayTagJsonConverter.cs @@ -0,0 +1,124 @@ +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace BandoWare.GameplayTags +{ + public class GameplayTagJsonConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, GameplayTag value, JsonSerializer serializer) + { + JObject obj = new JObject + { + { "tagName", value.IsNone ? "" : value.Name } + }; + obj.WriteTo(writer); + } + + public override GameplayTag ReadJson(JsonReader reader, Type objectType, GameplayTag existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jObject = JObject.Load(reader); + string tagName = jObject["tagName"]?.Value(); + + if (string.IsNullOrEmpty(tagName)) + return GameplayTag.None; + + return GameplayTagManager.RequestTag(tagName); + } + } + + public class GameplayTagContainerJsonConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, GameplayTagContainer value, JsonSerializer serializer) + { + if (value == null) + { + writer.WriteNull(); + return; + } + + JArray tagsArray = new JArray(); + + foreach (GameplayTag tag in value.GetExplicitTags()) + { + JObject tagObj = new JObject + { + { "tagName", tag.ToString() } + }; + tagsArray.Add(tagObj); + } + + JObject containerObj = new JObject + { + { "gameplayTags", tagsArray } + }; + + containerObj.WriteTo(writer); + } + + public override GameplayTagContainer ReadJson(JsonReader reader, Type objectType, GameplayTagContainer existingValue, bool hasExistingValue, JsonSerializer serializer) + { + JObject jObject = JObject.Load(reader); + JArray tagsArray = jObject["gameplayTags"] as JArray; + + GameplayTagContainer container = new GameplayTagContainer(); + + if (tagsArray == null) + return container; + + foreach (JObject tagObj in tagsArray) + { + string tagName = tagObj["tagName"]?.Value(); + + if (string.IsNullOrEmpty(tagName)) + continue; + + GameplayTag tag = GameplayTagManager.RequestTag(tagName); + if (tag.IsValid) + container.AddTag(tag); + } + + return container; + } + } + + public static class GameplayTagJsonSettings + { + private static JsonSerializerSettings s_Settings; + + public static JsonSerializerSettings Settings + { + get + { + if (s_Settings == null) + { + s_Settings = new JsonSerializerSettings + { + Converters = new JsonConverter[] + { + new GameplayTagJsonConverter(), + new GameplayTagContainerJsonConverter() + } + }; + } + return s_Settings; + } + } + + /// + /// Serializes an object to JSON using GameplayTag converters. + /// + public static string Serialize(object obj) + { + return JsonConvert.SerializeObject(obj, Settings); + } + + /// + /// Deserializes JSON to an object using GameplayTag converters. + /// + public static T Deserialize(string json) + { + return JsonConvert.DeserializeObject(json, Settings); + } + } +} diff --git a/Runtime/GameplayTagJsonConverter.cs.meta b/Runtime/GameplayTagJsonConverter.cs.meta new file mode 100644 index 0000000..813bd83 --- /dev/null +++ b/Runtime/GameplayTagJsonConverter.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 3a82538a26b0ba64282f09f70a5859d4 \ No newline at end of file