1+ using Newtonsoft . Json ;
2+ using UnityEngine ;
3+ using System ;
4+
5+ // ReSharper disable once CheckNamespace
6+
7+ namespace GameLovers
8+ {
9+ /// <summary>
10+ /// JSON converter for Unity's Color struct that handles serialization to/from:
11+ /// - Hex color strings (e.g. "#FF0000FF" for red)
12+ /// - RGBA object format (e.g. {"r":1,"g":0,"b":0,"a":1})
13+ /// </summary>
14+ /// <remarks>
15+ /// This converter enables proper serialization of Unity Color objects with Newtonsoft.Json.
16+ /// It's particularly useful for saving color data in JSON configuration files or network payloads.
17+ /// </remarks>
18+ public class ColorJsonConverter : JsonConverter < Color >
19+ {
20+ /// <summary>
21+ /// Reads JSON data and converts it to a Unity Color object
22+ /// </summary>
23+ /// <param name="reader">JSON reader providing the input data</param>
24+ /// <param name="objectType">Type of object to deserialize (should be Color)</param>
25+ /// <param name="existingValue">Existing value of the object being read</param>
26+ /// <param name="hasExistingValue">Whether there is an existing value</param>
27+ /// <param name="serializer">JSON serializer instance</param>
28+ /// <returns>Deserialized Color object</returns>
29+ /// <remarks>
30+ /// Supports both hex color strings and RGBA object formats:
31+ /// - "#RRGGBBAA" or "#RRGGBB" (missing alpha defaults to 1)
32+ /// - {"r":1,"g":0,"b":0,"a":1} (missing components default to 0, except alpha which defaults to 1)
33+ /// </remarks>
34+ public override Color ReadJson ( JsonReader reader , Type objectType , Color existingValue , bool hasExistingValue , JsonSerializer serializer )
35+ {
36+ if ( reader . TokenType == JsonToken . String )
37+ {
38+ string colorString = reader . Value . ToString ( ) ;
39+ Color color ;
40+ if ( ColorUtility . TryParseHtmlString ( colorString , out color ) )
41+ {
42+ return color ;
43+ }
44+ }
45+ else if ( reader . TokenType == JsonToken . StartObject )
46+ {
47+ float r = 0 , g = 0 , b = 0 , a = 1 ;
48+
49+ reader . Read ( ) ;
50+ while ( reader . TokenType != JsonToken . EndObject )
51+ {
52+ string propertyName = reader . Value . ToString ( ) . ToLower ( ) ;
53+ reader . Read ( ) ;
54+
55+ switch ( propertyName )
56+ {
57+ case "r" : r = Convert . ToSingle ( reader . Value ) ; break ;
58+ case "g" : g = Convert . ToSingle ( reader . Value ) ; break ;
59+ case "b" : b = Convert . ToSingle ( reader . Value ) ; break ;
60+ case "a" : a = Convert . ToSingle ( reader . Value ) ; break ;
61+ }
62+
63+ reader . Read ( ) ;
64+ }
65+
66+ return new Color ( r , g , b , a ) ;
67+ }
68+
69+ return Color . white ;
70+ }
71+
72+ /// <summary>
73+ /// Writes a Color object to JSON format
74+ /// </summary>
75+ /// <param name="writer">JSON writer for output</param>
76+ /// <param name="value">Color value to serialize</param>
77+ /// <param name="serializer">JSON serializer instance</param>
78+ /// <remarks>
79+ /// Always serializes to hex string format (e.g. "#FF0000FF" for red)
80+ /// This provides a compact and web-friendly representation
81+ /// </remarks>
82+ public override void WriteJson ( JsonWriter writer , Color value , JsonSerializer serializer )
83+ {
84+ writer . WriteValue ( "#" + ColorUtility . ToHtmlStringRGBA ( value ) ) ;
85+ }
86+ }
87+ }
0 commit comments