For Newtonsoft.Json
you can use a StringEnumConverter
and pass it along into
var converter = new StringEnumConverter();
var json = JsonConvert.SerializeObject(example, Formatting.Indented, converter);
and (actually optional apparently)
var example = JsonConvert.DeserializeObject<Example>(json, converter);
in my test for deserializing it seems to also work with only
var example = JsonConvert.DeserializeObject<Example>(json);
For System.Text.Json
you can use the equivalent JsonStringEnumConverter
and pass it via the options like e.g.
// IncludeFields depends on whether your type uses fields or properties
// by default System.Text.Json only considers properties
// so to reflect the behavior of Newtonsoft I enabled also fields
var options = new JsonSerializerOptions() { WriteIndented = true, IncludeFields = true };
options.Converters.Add(new JsonStringEnumConverter());
var json = JsonSerializer.Serialize(example, options);
and
var example = JsonSerializer.Deserialize<Example>(json, options);
.Net Fiddle for both above
Note (also applies to JsonUtility
below): Both basically go through ToString
and Enum.Parse
so in the json it will read e.g.
"FOREST, SWAMP"
if for some reason you really want FOREST|SWAMP
instead you will have to implement your own custom JsonConverter
(Newtonsoft) or accordingly JsonConverter
(System.Text.Json).
Basically using the same and do something like (pseudo code)
// When serializing Terrain -> string
var enumString = value.ToString().Replace(", ", "|");
and
// When deserializing string -> Terrain
var enumValue = (Terrain)Enum.Parse(enumString.Replace("|", ", "));
For built-in JsonUtility
afaik there is unfortunately nothing similar. You instead have to overwrite the serialization of the entire class like e.g.
public class Example : ISerializationCallbackReceiver
{
public string Name;
[NonSerialized]
public Terrain Terrain;
public int SomeVlaue;
[SerializeField]
private string terrain;
public void OnBeforeSerialize()
{
terrain = Terrain.ToString();
}
public void OnAfterDeserialize()
{
Terrain = (Terrain)Enum.Parse(typeof(Terrain), terrain);
}
}
NOTE:
- Have in mind though that this will also affect the way it is displayed in the Inspector => You might then want to implement a custom Inspector to basically "revert" the display and draw it as an enum flag field again.
- You also will have to repeat this for each and every type that contains a
Terrain
and shall be json serialized