SHA256
Add Preset System
This commit is contained in:
7 files changed
+931
-151
No files matched your search
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ADOFAIRenderer.Data;
|
||||
|
||||
/// <summary>
|
||||
/// Converts Unity <see cref="Color"/> and nullable <see cref="Color"/> to and from hex string (#RRGGBBAA).
|
||||
/// Pure C# implementation to completely avoid Unity internal native ECalls (such as Color.linear or ColorUtility.TryParseHtmlString).
|
||||
/// </summary>
|
||||
public class ColorJsonConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof(Color) || objectType == typeof(Color?);
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteNull();
|
||||
return;
|
||||
}
|
||||
|
||||
var color = (Color)value;
|
||||
writer.WriteValue(ToHex(color));
|
||||
}
|
||||
|
||||
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
||||
{
|
||||
bool isNullable = Nullable.GetUnderlyingType(objectType) != null || !objectType.IsValueType;
|
||||
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return isNullable ? null : (object)default(Color);
|
||||
}
|
||||
|
||||
if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
var str = (string?)reader.Value;
|
||||
if (TryParseHex(str, out var parsedColor))
|
||||
{
|
||||
return parsedColor;
|
||||
}
|
||||
|
||||
return isNullable ? null : (object)default(Color);
|
||||
}
|
||||
|
||||
if (reader.TokenType == JsonToken.StartObject)
|
||||
{
|
||||
var obj = JObject.Load(reader);
|
||||
float r = (float?)obj["r"] ?? 0f;
|
||||
float g = (float?)obj["g"] ?? 0f;
|
||||
float b = (float?)obj["b"] ?? 0f;
|
||||
float a = (float?)obj["a"] ?? 1f;
|
||||
return new Color(r, g, b, a);
|
||||
}
|
||||
|
||||
return isNullable ? null : (object)default(Color);
|
||||
}
|
||||
|
||||
public static string ToHex(Color color)
|
||||
{
|
||||
byte r = (byte)Math.Clamp((int)Math.Round(color.r * 255f), 0, 255);
|
||||
byte g = (byte)Math.Clamp((int)Math.Round(color.g * 255f), 0, 255);
|
||||
byte b = (byte)Math.Clamp((int)Math.Round(color.b * 255f), 0, 255);
|
||||
byte a = (byte)Math.Clamp((int)Math.Round(color.a * 255f), 0, 255);
|
||||
return $"#{r:X2}{g:X2}{b:X2}{a:X2}";
|
||||
}
|
||||
|
||||
public static bool TryParseHex(string? hex, out Color color)
|
||||
{
|
||||
color = default;
|
||||
if (string.IsNullOrWhiteSpace(hex)) return false;
|
||||
|
||||
var str = hex.Trim();
|
||||
if (str.StartsWith("#"))
|
||||
{
|
||||
str = str.Substring(1);
|
||||
}
|
||||
|
||||
if (str.Length == 6)
|
||||
{
|
||||
if (byte.TryParse(str.Substring(0, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var r) &&
|
||||
byte.TryParse(str.Substring(2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var g) &&
|
||||
byte.TryParse(str.Substring(4, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var b))
|
||||
{
|
||||
color = new Color(r / 255f, g / 255f, b / 255f, 1f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (str.Length == 8)
|
||||
{
|
||||
if (byte.TryParse(str.Substring(0, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var r) &&
|
||||
byte.TryParse(str.Substring(2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var g) &&
|
||||
byte.TryParse(str.Substring(4, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var b) &&
|
||||
byte.TryParse(str.Substring(6, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var a))
|
||||
{
|
||||
color = new Color(r / 255f, g / 255f, b / 255f, a / 255f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user