com.wallstop-studios.unity-helpers 2.0.0-rc48 → 2.0.0-rc50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 1,
3
+ "isRoot": true,
4
+ "tools": {
5
+ "CSharpier": {
6
+ "version": "0.30.6",
7
+ "commands": ["dotnet-csharpier"]
8
+ }
9
+ }
10
+ }
package/.editorconfig ADDED
@@ -0,0 +1,184 @@
1
+
2
+ [*]
3
+ charset = utf-8-bom
4
+ end_of_line = crlf
5
+ trim_trailing_whitespace = false
6
+ insert_final_newline = false
7
+ indent_style = space
8
+ indent_size = 4
9
+
10
+ # Microsoft .NET properties
11
+ csharp_new_line_before_members_in_object_initializers = false
12
+ csharp_preferred_modifier_order = public, private, protected, internal, file, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async, required:suggestion
13
+ csharp_prefer_braces = true:suggestion
14
+ csharp_style_prefer_utf8_string_literals = true:suggestion
15
+ csharp_style_var_elsewhere = false:suggestion
16
+ csharp_style_var_for_built_in_types = false:suggestion
17
+ csharp_style_var_when_type_is_apparent = false:suggestion
18
+ csharp_using_directive_placement = inside_namespace:silent
19
+ dotnet_naming_rule.event_rule.import_to_resharper = True
20
+ dotnet_naming_rule.event_rule.resharper_description = Events
21
+ dotnet_naming_rule.event_rule.resharper_guid = 0c4c6401-2a1f-4db1-a21f-562f51542cf8
22
+ dotnet_naming_rule.event_rule.severity = warning
23
+ dotnet_naming_rule.event_rule.style = on_upper_camel_case_style
24
+ dotnet_naming_rule.event_rule.symbols = event_symbols
25
+ dotnet_naming_rule.interfaces_rule.import_to_resharper = True
26
+ dotnet_naming_rule.interfaces_rule.resharper_description = Interfaces
27
+ dotnet_naming_rule.interfaces_rule.resharper_guid = a7a3339e-4e89-4319-9735-a9dc4cb74cc7
28
+ dotnet_naming_rule.interfaces_rule.severity = warning
29
+ dotnet_naming_rule.interfaces_rule.style = i_upper_camel_case_style
30
+ dotnet_naming_rule.interfaces_rule.symbols = interfaces_symbols
31
+ dotnet_naming_rule.local_constants_rule.import_to_resharper = True
32
+ dotnet_naming_rule.local_constants_rule.resharper_description = Local constants
33
+ dotnet_naming_rule.local_constants_rule.resharper_guid = a4f433b8-abcd-4e55-a08f-82e78cef0f0c
34
+ dotnet_naming_rule.local_constants_rule.resharper_style = AaBb, aaBb
35
+ dotnet_naming_rule.local_constants_rule.severity = warning
36
+ dotnet_naming_rule.local_constants_rule.style = upper_camel_case_style
37
+ dotnet_naming_rule.local_constants_rule.symbols = local_constants_symbols
38
+ dotnet_naming_rule.public_fields_override_rule.import_to_resharper = False
39
+ dotnet_naming_rule.public_fields_override_rule.severity = warning
40
+ dotnet_naming_rule.public_fields_override_rule.style = upper_camel_case_style
41
+ dotnet_naming_rule.public_fields_override_rule.symbols = public_fields_override_symbols
42
+ dotnet_naming_rule.public_fields_override_rule_1.import_to_resharper = False
43
+ dotnet_naming_rule.public_fields_override_rule_1.severity = warning
44
+ dotnet_naming_rule.public_fields_override_rule_1.style = upper_camel_case_style
45
+ dotnet_naming_rule.public_fields_override_rule_1.symbols = public_fields_override_symbols_1
46
+ dotnet_naming_rule.public_fields_rule.import_to_resharper = True
47
+ dotnet_naming_rule.public_fields_rule.resharper_description = Instance fields (not private)
48
+ dotnet_naming_rule.public_fields_rule.resharper_guid = 53eecf85-d821-40e8-ac97-fdb734542b84
49
+ dotnet_naming_rule.public_fields_rule.severity = warning
50
+ dotnet_naming_rule.public_fields_rule.style = lower_camel_case_style
51
+ dotnet_naming_rule.public_fields_rule.symbols = public_fields_symbols
52
+ dotnet_naming_rule.public_static_fields_rule.import_to_resharper = True
53
+ dotnet_naming_rule.public_static_fields_rule.resharper_description = Static fields (not private)
54
+ dotnet_naming_rule.public_static_fields_rule.resharper_guid = 70345118-4b40-4ece-937c-bbeb7a0b2e70
55
+ dotnet_naming_rule.public_static_fields_rule.severity = warning
56
+ dotnet_naming_rule.public_static_fields_rule.style = upper_camel_case_style
57
+ dotnet_naming_rule.public_static_fields_rule.symbols = public_static_fields_symbols
58
+ dotnet_naming_rule.type_parameters_rule.import_to_resharper = True
59
+ dotnet_naming_rule.type_parameters_rule.resharper_description = Type parameters
60
+ dotnet_naming_rule.type_parameters_rule.resharper_guid = 2c62818f-621b-4425-adc9-78611099bfcb
61
+ dotnet_naming_rule.type_parameters_rule.severity = warning
62
+ dotnet_naming_rule.type_parameters_rule.style = t_upper_camel_case_style
63
+ dotnet_naming_rule.type_parameters_rule.symbols = type_parameters_symbols
64
+ dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
65
+ dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
66
+ dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
67
+ dotnet_naming_rule.unity_serialized_field_rule.severity = none
68
+ dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style
69
+ dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
70
+ dotnet_naming_style.i_upper_camel_case_style.capitalization = pascal_case
71
+ dotnet_naming_style.i_upper_camel_case_style.required_prefix = I
72
+ dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
73
+ dotnet_naming_style.on_upper_camel_case_style.capitalization = pascal_case
74
+ dotnet_naming_style.on_upper_camel_case_style.required_prefix = On
75
+ dotnet_naming_style.t_upper_camel_case_style.capitalization = pascal_case
76
+ dotnet_naming_style.t_upper_camel_case_style.required_prefix = T
77
+ dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case
78
+ dotnet_naming_symbols.event_symbols.applicable_accessibilities = *
79
+ dotnet_naming_symbols.event_symbols.applicable_kinds = event
80
+ dotnet_naming_symbols.event_symbols.resharper_applicable_kinds = event
81
+ dotnet_naming_symbols.event_symbols.resharper_required_modifiers = any
82
+ dotnet_naming_symbols.interfaces_symbols.applicable_accessibilities = *
83
+ dotnet_naming_symbols.interfaces_symbols.applicable_kinds = interface
84
+ dotnet_naming_symbols.interfaces_symbols.resharper_applicable_kinds = interface
85
+ dotnet_naming_symbols.interfaces_symbols.resharper_required_modifiers = any
86
+ dotnet_naming_symbols.local_constants_symbols.applicable_accessibilities = *
87
+ dotnet_naming_symbols.local_constants_symbols.applicable_kinds = local
88
+ dotnet_naming_symbols.local_constants_symbols.required_modifiers = const
89
+ dotnet_naming_symbols.local_constants_symbols.resharper_applicable_kinds = local_constant
90
+ dotnet_naming_symbols.local_constants_symbols.resharper_required_modifiers = any
91
+ dotnet_naming_symbols.public_fields_override_symbols.applicable_accessibilities = public
92
+ dotnet_naming_symbols.public_fields_override_symbols.applicable_kinds = field
93
+ dotnet_naming_symbols.public_fields_override_symbols.required_modifiers = const
94
+ dotnet_naming_symbols.public_fields_override_symbols_1.applicable_accessibilities = public
95
+ dotnet_naming_symbols.public_fields_override_symbols_1.applicable_kinds = field
96
+ dotnet_naming_symbols.public_fields_override_symbols_1.required_modifiers = readonly,static
97
+ dotnet_naming_symbols.public_fields_symbols.applicable_accessibilities = public
98
+ dotnet_naming_symbols.public_fields_symbols.applicable_kinds = field
99
+ dotnet_naming_symbols.public_fields_symbols.resharper_applicable_kinds = field,readonly_field
100
+ dotnet_naming_symbols.public_fields_symbols.resharper_required_modifiers = instance
101
+ dotnet_naming_symbols.public_static_fields_symbols.applicable_accessibilities = public
102
+ dotnet_naming_symbols.public_static_fields_symbols.applicable_kinds = field
103
+ dotnet_naming_symbols.public_static_fields_symbols.required_modifiers = static
104
+ dotnet_naming_symbols.public_static_fields_symbols.resharper_applicable_kinds = field
105
+ dotnet_naming_symbols.public_static_fields_symbols.resharper_required_modifiers = static
106
+ dotnet_naming_symbols.type_parameters_symbols.applicable_accessibilities = *
107
+ dotnet_naming_symbols.type_parameters_symbols.applicable_kinds = type_parameter
108
+ dotnet_naming_symbols.type_parameters_symbols.resharper_applicable_kinds = type_parameter
109
+ dotnet_naming_symbols.type_parameters_symbols.resharper_required_modifiers = any
110
+ dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
111
+ dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
112
+ dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
113
+ dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
114
+ dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
115
+ dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none
116
+ dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
117
+ dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
118
+ dotnet_style_predefined_type_for_member_access = true:suggestion
119
+ dotnet_style_qualification_for_event = false:suggestion
120
+ dotnet_style_qualification_for_field = false:suggestion
121
+ dotnet_style_qualification_for_method = false:suggestion
122
+ dotnet_style_qualification_for_property = false:suggestion
123
+ dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
124
+
125
+ # ReSharper properties
126
+ resharper_autodetect_indent_settings = true
127
+ resharper_braces_redundant = true
128
+ resharper_csharp_wrap_lines = false
129
+ resharper_formatter_off_tag = @formatter:off
130
+ resharper_formatter_on_tag = @formatter:on
131
+ resharper_formatter_tags_enabled = true
132
+ resharper_indent_preprocessor_directives = normal
133
+ resharper_keep_existing_attribute_arrangement = true
134
+ resharper_place_attribute_on_same_line = false
135
+ resharper_show_autodetect_configure_formatting_tip = false
136
+ resharper_use_indent_from_vs = false
137
+
138
+ # ReSharper inspection severities
139
+ resharper_arrange_redundant_parentheses_highlighting = hint
140
+ resharper_arrange_this_qualifier_highlighting = hint
141
+ resharper_arrange_trailing_comma_in_multiline_lists_highlighting = none
142
+ resharper_arrange_type_member_modifiers_highlighting = hint
143
+ resharper_arrange_type_modifiers_highlighting = hint
144
+ resharper_built_in_type_reference_style_for_member_access_highlighting = hint
145
+ resharper_built_in_type_reference_style_highlighting = hint
146
+ resharper_mvc_action_not_resolved_highlighting = warning
147
+ resharper_mvc_area_not_resolved_highlighting = warning
148
+ resharper_mvc_controller_not_resolved_highlighting = warning
149
+ resharper_mvc_masterpage_not_resolved_highlighting = warning
150
+ resharper_mvc_partial_view_not_resolved_highlighting = warning
151
+ resharper_mvc_template_not_resolved_highlighting = warning
152
+ resharper_mvc_view_component_not_resolved_highlighting = warning
153
+ resharper_mvc_view_component_view_not_resolved_highlighting = warning
154
+ resharper_mvc_view_not_resolved_highlighting = warning
155
+ resharper_prefer_concrete_value_over_default_highlighting = none
156
+ resharper_razor_assembly_not_resolved_highlighting = warning
157
+ resharper_redundant_base_qualifier_highlighting = warning
158
+ resharper_suggest_var_or_type_built_in_types_highlighting = hint
159
+ resharper_suggest_var_or_type_elsewhere_highlighting = hint
160
+ resharper_suggest_var_or_type_simple_types_highlighting = hint
161
+ resharper_web_config_module_not_resolved_highlighting = warning
162
+ resharper_web_config_type_not_resolved_highlighting = warning
163
+ resharper_web_config_wrong_module_highlighting = warning
164
+
165
+ [{*.har,*.inputactions,*.jsb2,*.jsb3,*.json,*.jsonc,*.postman_collection,*.postman_collection.json,*.postman_environment,*.postman_environment.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,.ws-context,jest.config}]
166
+ indent_style = space
167
+ indent_size = 2
168
+
169
+ [{*.yaml,*.yml}]
170
+ indent_style = space
171
+ indent_size = 2
172
+
173
+ [*.asmdef]
174
+ indent_style = space
175
+ indent_size = 2
176
+
177
+ [*.asmref]
178
+ indent_style = space
179
+ indent_size = 2
180
+
181
+ [*.{appxmanifest,asax,ascx,aspx,axaml,blockshader,build,c,c++,c++m,cc,ccm,cginc,compute,cp,cpp,cppm,cs,cshtml,cu,cuh,cxx,cxxm,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,h++,hh,hlsl,hlsli,hlslinc,hp,hpp,hxx,icc,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,mxx,nuspec,paml,razor,resw,resx,shader,shaderFoundry,skin,tcc,tpp,urtshader,usf,ush,uxml,vb,xaml,xamlx,xoml,xsd}]
182
+ indent_style = space
183
+ indent_size = 4
184
+ tab_width = 4
@@ -0,0 +1,22 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: dotnet-tool-restore
5
+ name: Install .NET tools
6
+ entry: dotnet tool restore
7
+ language: system
8
+ always_run: true
9
+ pass_filenames: false
10
+ stages:
11
+ - pre-commit
12
+ - pre-push
13
+ - post-checkout
14
+ - post-rewrite
15
+ description: Install the .NET tools listed at .config/dotnet-tools.json.
16
+ - id: csharpier
17
+ name: Run CSharpier on C# files
18
+ entry: dotnet tool run dotnet-csharpier
19
+ language: system
20
+ types:
21
+ - c#
22
+ description: CSharpier is an opinionated C# formatter inspired by Prettier.
package/README.md CHANGED
@@ -171,4 +171,8 @@ Assert.AreEqual(myCoolGameObject, nearestNeighbors[0]);
171
171
  ```
172
172
 
173
173
  ## Note
174
- All spatial trees expect the positional data to be *immutable*. It is very important that the positions do not change. If they do, you will need to reconstruct the tree.
174
+ All spatial trees expect the positional data to be *immutable*. It is very important that the positions do not change. If they do, you will need to reconstruct the tree.
175
+
176
+ ## Contributing
177
+
178
+ This project uses [CSharpier](https://csharpier.com/) with the default configuration to enable an enforced, consistent style. If you would like to contribute, recommendation is to ensure that changed files are ran through CSharpier prior to merge. This can be done automatically through editor plugins, or, minimally, by installing a [pre-commit hook](https://pre-commit.com/#3-install-the-git-hook-scripts).
@@ -0,0 +1,88 @@
1
+ namespace UnityHelpers.Core.Serialization.JsonConverters
2
+ {
3
+ using System;
4
+ using System.Text.Json;
5
+ using System.Text.Json.Serialization;
6
+ using UnityEngine;
7
+
8
+ public sealed class ColorConverter : JsonConverter<Color>
9
+ {
10
+ public static readonly ColorConverter Instance = new();
11
+
12
+ private ColorConverter() { }
13
+
14
+ public override Color Read(
15
+ ref Utf8JsonReader reader,
16
+ Type typeToConvert,
17
+ JsonSerializerOptions options
18
+ )
19
+ {
20
+ if (reader.TokenType != JsonTokenType.StartObject)
21
+ {
22
+ throw new JsonException($"Invalid token type {reader.TokenType}");
23
+ }
24
+
25
+ float r = 0;
26
+ float g = 0;
27
+ float b = 0;
28
+ float a = 1;
29
+
30
+ while (reader.Read())
31
+ {
32
+ if (reader.TokenType == JsonTokenType.EndObject)
33
+ {
34
+ return new Color(r, g, b, a);
35
+ }
36
+
37
+ if (reader.TokenType == JsonTokenType.PropertyName)
38
+ {
39
+ string propertyName = reader.GetString();
40
+ reader.Read();
41
+ switch (propertyName)
42
+ {
43
+ case "r":
44
+ {
45
+ r = reader.GetSingle();
46
+ break;
47
+ }
48
+ case "g":
49
+ {
50
+ g = reader.GetSingle();
51
+ break;
52
+ }
53
+ case "b":
54
+ {
55
+ b = reader.GetSingle();
56
+ break;
57
+ }
58
+ case "a":
59
+ {
60
+ a = reader.GetSingle();
61
+ break;
62
+ }
63
+ default:
64
+ {
65
+ throw new JsonException($"Unknown property: {propertyName}");
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ throw new JsonException("Incomplete JSON for Color");
72
+ }
73
+
74
+ public override void Write(
75
+ Utf8JsonWriter writer,
76
+ Color value,
77
+ JsonSerializerOptions options
78
+ )
79
+ {
80
+ writer.WriteStartObject();
81
+ writer.WriteNumber("r", value.r);
82
+ writer.WriteNumber("g", value.g);
83
+ writer.WriteNumber("b", value.b);
84
+ writer.WriteNumber("a", value.a);
85
+ writer.WriteEndObject();
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 637013e97e6d436a880092e239d12e4e
3
+ timeCreated: 1743567974
@@ -0,0 +1,37 @@
1
+ namespace UnityHelpers.Core.Serialization.JsonConverters
2
+ {
3
+ using System;
4
+ using System.Text.Json;
5
+ using System.Text.Json.Serialization;
6
+ using UnityEngine;
7
+ using Object = UnityEngine.Object;
8
+
9
+ public sealed class GameObjectConverter : JsonConverter<GameObject>
10
+ {
11
+ public static readonly GameObjectConverter Instance = new();
12
+
13
+ private GameObjectConverter() { }
14
+
15
+ public override GameObject Read(
16
+ ref Utf8JsonReader reader,
17
+ Type typeToConvert,
18
+ JsonSerializerOptions options
19
+ )
20
+ {
21
+ throw new NotImplementedException(nameof(Read));
22
+ }
23
+
24
+ public override void Write(
25
+ Utf8JsonWriter writer,
26
+ GameObject value,
27
+ JsonSerializerOptions options
28
+ )
29
+ {
30
+ writer.WriteStringValue(
31
+ value == null
32
+ ? "{}"
33
+ : new { name = value.name, type = value.GetType().FullName }.ToString()
34
+ );
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 6c12adc5c56c4be9bb536628749979b0
3
+ timeCreated: 1743567258
@@ -0,0 +1,218 @@
1
+ namespace UnityHelpers.Core.Serialization.JsonConverters
2
+ {
3
+ using System;
4
+ using System.Text.Json;
5
+ using System.Text.Json.Serialization;
6
+ using UnityEngine;
7
+
8
+ public sealed class Matrix4x4Converter : JsonConverter<Matrix4x4>
9
+ {
10
+ private static readonly string[] PropertyNames =
11
+ {
12
+ "m00",
13
+ "m01",
14
+ "m02",
15
+ "m03",
16
+ "m10",
17
+ "m11",
18
+ "m12",
19
+ "m13",
20
+ "m20",
21
+ "m21",
22
+ "m22",
23
+ "m23",
24
+ "m30",
25
+ "m31",
26
+ "m32",
27
+ "m33",
28
+ };
29
+
30
+ public static readonly Matrix4x4Converter Instance = new();
31
+
32
+ private Matrix4x4Converter() { }
33
+
34
+ public override Matrix4x4 Read(
35
+ ref Utf8JsonReader reader,
36
+ Type typeToConvert,
37
+ JsonSerializerOptions options
38
+ )
39
+ {
40
+ if (reader.TokenType != JsonTokenType.StartObject)
41
+ {
42
+ throw new JsonException("Expected StartObject token when parsing Matrix4x4.");
43
+ }
44
+
45
+ float m00 = 0;
46
+ float m01 = 0;
47
+ float m02 = 0;
48
+ float m03 = 0;
49
+ float m10 = 0;
50
+ float m11 = 0;
51
+ float m12 = 0;
52
+ float m13 = 0;
53
+ float m20 = 0;
54
+ float m21 = 0;
55
+ float m22 = 0;
56
+ float m23 = 0;
57
+ float m30 = 0;
58
+ float m31 = 0;
59
+ float m32 = 0;
60
+ float m33 = 0;
61
+
62
+ bool[] found = new bool[16];
63
+
64
+ while (reader.Read())
65
+ {
66
+ if (reader.TokenType == JsonTokenType.EndObject)
67
+ {
68
+ break;
69
+ }
70
+ if (reader.TokenType != JsonTokenType.PropertyName)
71
+ {
72
+ throw new JsonException("Expected property name in Matrix4x4 JSON.");
73
+ }
74
+ string propertyName = reader.GetString();
75
+ if (!reader.Read())
76
+ {
77
+ throw new JsonException($"Expected value for property '{propertyName}'.");
78
+ }
79
+ float value;
80
+ try
81
+ {
82
+ value = reader.GetSingle();
83
+ }
84
+ catch (Exception ex)
85
+ {
86
+ throw new JsonException($"Invalid value for property '{propertyName}'.", ex);
87
+ }
88
+ switch (propertyName)
89
+ {
90
+ case "m00":
91
+ m00 = value;
92
+ found[0] = true;
93
+ break;
94
+ case "m01":
95
+ m01 = value;
96
+ found[1] = true;
97
+ break;
98
+ case "m02":
99
+ m02 = value;
100
+ found[2] = true;
101
+ break;
102
+ case "m03":
103
+ m03 = value;
104
+ found[3] = true;
105
+ break;
106
+ case "m10":
107
+ m10 = value;
108
+ found[4] = true;
109
+ break;
110
+ case "m11":
111
+ m11 = value;
112
+ found[5] = true;
113
+ break;
114
+ case "m12":
115
+ m12 = value;
116
+ found[6] = true;
117
+ break;
118
+ case "m13":
119
+ m13 = value;
120
+ found[7] = true;
121
+ break;
122
+ case "m20":
123
+ m20 = value;
124
+ found[8] = true;
125
+ break;
126
+ case "m21":
127
+ m21 = value;
128
+ found[9] = true;
129
+ break;
130
+ case "m22":
131
+ m22 = value;
132
+ found[10] = true;
133
+ break;
134
+ case "m23":
135
+ m23 = value;
136
+ found[11] = true;
137
+ break;
138
+ case "m30":
139
+ m30 = value;
140
+ found[12] = true;
141
+ break;
142
+ case "m31":
143
+ m31 = value;
144
+ found[13] = true;
145
+ break;
146
+ case "m32":
147
+ m32 = value;
148
+ found[14] = true;
149
+ break;
150
+ case "m33":
151
+ m33 = value;
152
+ found[15] = true;
153
+ break;
154
+ }
155
+ }
156
+
157
+ for (int i = 0; i < found.Length; i++)
158
+ {
159
+ if (!found[i])
160
+ {
161
+ throw new JsonException(
162
+ $"Missing property '{PropertyNames[i]}' for Matrix4x4."
163
+ );
164
+ }
165
+ }
166
+
167
+ Matrix4x4 matrix = new()
168
+ {
169
+ m00 = m00,
170
+ m01 = m01,
171
+ m02 = m02,
172
+ m03 = m03,
173
+ m10 = m10,
174
+ m11 = m11,
175
+ m12 = m12,
176
+ m13 = m13,
177
+ m20 = m20,
178
+ m21 = m21,
179
+ m22 = m22,
180
+ m23 = m23,
181
+ m30 = m30,
182
+ m31 = m31,
183
+ m32 = m32,
184
+ m33 = m33,
185
+ };
186
+
187
+ return matrix;
188
+ }
189
+
190
+ public override void Write(
191
+ Utf8JsonWriter writer,
192
+ Matrix4x4 matrix,
193
+ JsonSerializerOptions options
194
+ )
195
+ {
196
+ writer.WriteStartObject();
197
+
198
+ writer.WriteNumber("m00", matrix.m00);
199
+ writer.WriteNumber("m01", matrix.m01);
200
+ writer.WriteNumber("m02", matrix.m02);
201
+ writer.WriteNumber("m03", matrix.m03);
202
+ writer.WriteNumber("m10", matrix.m10);
203
+ writer.WriteNumber("m11", matrix.m11);
204
+ writer.WriteNumber("m12", matrix.m12);
205
+ writer.WriteNumber("m13", matrix.m13);
206
+ writer.WriteNumber("m20", matrix.m20);
207
+ writer.WriteNumber("m21", matrix.m21);
208
+ writer.WriteNumber("m22", matrix.m22);
209
+ writer.WriteNumber("m23", matrix.m23);
210
+ writer.WriteNumber("m30", matrix.m30);
211
+ writer.WriteNumber("m31", matrix.m31);
212
+ writer.WriteNumber("m32", matrix.m32);
213
+ writer.WriteNumber("m33", matrix.m33);
214
+
215
+ writer.WriteEndObject();
216
+ }
217
+ }
218
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 456d0090c1d744de924e8f18a895b87b
3
+ timeCreated: 1743568330
@@ -0,0 +1,28 @@
1
+ namespace UnityHelpers.Core.Serialization.JsonConverters
2
+ {
3
+ using System;
4
+ using System.Text.Json;
5
+ using System.Text.Json.Serialization;
6
+
7
+ public sealed class TypeConverter : JsonConverter<Type>
8
+ {
9
+ public static readonly TypeConverter Instance = new();
10
+
11
+ private TypeConverter() { }
12
+
13
+ public override Type Read(
14
+ ref Utf8JsonReader reader,
15
+ Type typeToConvert,
16
+ JsonSerializerOptions options
17
+ )
18
+ {
19
+ string typeName = reader.GetString();
20
+ return string.IsNullOrWhiteSpace(typeName) ? null : Type.GetType(typeName);
21
+ }
22
+
23
+ public override void Write(Utf8JsonWriter writer, Type value, JsonSerializerOptions options)
24
+ {
25
+ writer.WriteStringValue(value?.AssemblyQualifiedName);
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: ffebfa399370464baa7e9d9065db60f5
3
+ timeCreated: 1743566193
@@ -22,8 +22,8 @@
22
22
  throw new JsonException($"Invalid token type {reader.TokenType}");
23
23
  }
24
24
 
25
- float x = 0,
26
- y = 0;
25
+ float x = 0;
26
+ float y = 0;
27
27
 
28
28
  while (reader.Read())
29
29
  {
@@ -22,9 +22,9 @@
22
22
  throw new JsonException($"Invalid token type {reader.TokenType}");
23
23
  }
24
24
 
25
- float x = 0,
26
- y = 0,
27
- z = 0;
25
+ float x = 0;
26
+ float y = 0;
27
+ float z = 0;
28
28
 
29
29
  while (reader.Read())
30
30
  {
@@ -0,0 +1,88 @@
1
+ namespace UnityHelpers.Core.Serialization.JsonConverters
2
+ {
3
+ using System;
4
+ using System.Text.Json;
5
+ using System.Text.Json.Serialization;
6
+ using UnityEngine;
7
+
8
+ public sealed class Vector4Converter : JsonConverter<Vector4>
9
+ {
10
+ public static readonly Vector4Converter Instance = new();
11
+
12
+ private Vector4Converter() { }
13
+
14
+ public override Vector4 Read(
15
+ ref Utf8JsonReader reader,
16
+ Type typeToConvert,
17
+ JsonSerializerOptions options
18
+ )
19
+ {
20
+ if (reader.TokenType != JsonTokenType.StartObject)
21
+ {
22
+ throw new JsonException($"Invalid token type {reader.TokenType}");
23
+ }
24
+
25
+ float x = 0;
26
+ float y = 0;
27
+ float z = 0;
28
+ float w = 0;
29
+
30
+ while (reader.Read())
31
+ {
32
+ if (reader.TokenType == JsonTokenType.EndObject)
33
+ {
34
+ return new Vector4(x, y, z, w);
35
+ }
36
+
37
+ if (reader.TokenType == JsonTokenType.PropertyName)
38
+ {
39
+ string propertyName = reader.GetString();
40
+ reader.Read();
41
+ switch (propertyName)
42
+ {
43
+ case "x":
44
+ {
45
+ x = reader.GetSingle();
46
+ break;
47
+ }
48
+ case "y":
49
+ {
50
+ y = reader.GetSingle();
51
+ break;
52
+ }
53
+ case "z":
54
+ {
55
+ z = reader.GetSingle();
56
+ break;
57
+ }
58
+ case "w":
59
+ {
60
+ w = reader.GetSingle();
61
+ break;
62
+ }
63
+ default:
64
+ {
65
+ throw new JsonException($"Unknown property: {propertyName}");
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ throw new JsonException("Incomplete JSON for Vector4");
72
+ }
73
+
74
+ public override void Write(
75
+ Utf8JsonWriter writer,
76
+ Vector4 value,
77
+ JsonSerializerOptions options
78
+ )
79
+ {
80
+ writer.WriteStartObject();
81
+ writer.WriteNumber("x", value.x);
82
+ writer.WriteNumber("y", value.y);
83
+ writer.WriteNumber("z", value.z);
84
+ writer.WriteNumber("w", value.w);
85
+ writer.WriteEndObject();
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 89ed188581124a3abc07f3645220ef56
3
+ timeCreated: 1743568183
@@ -9,6 +9,7 @@
9
9
  using System.Text.Json.Serialization;
10
10
  using Extension;
11
11
  using JsonConverters;
12
+ using TypeConverter = JsonConverters.TypeConverter;
12
13
 
13
14
  internal static class SerializerEncoding
14
15
  {
@@ -31,6 +32,11 @@
31
32
  new JsonStringEnumConverter(),
32
33
  Vector3Converter.Instance,
33
34
  Vector2Converter.Instance,
35
+ Vector4Converter.Instance,
36
+ Matrix4x4Converter.Instance,
37
+ TypeConverter.Instance,
38
+ GameObjectConverter.Instance,
39
+ ColorConverter.Instance,
34
40
  },
35
41
  };
36
42
 
@@ -46,6 +52,11 @@
46
52
  new JsonStringEnumConverter(),
47
53
  Vector3Converter.Instance,
48
54
  Vector2Converter.Instance,
55
+ Vector4Converter.Instance,
56
+ Matrix4x4Converter.Instance,
57
+ TypeConverter.Instance,
58
+ GameObjectConverter.Instance,
59
+ ColorConverter.Instance,
49
60
  },
50
61
  WriteIndented = true,
51
62
  };
@@ -6,9 +6,11 @@
6
6
  using System.Runtime.Serialization;
7
7
  using System.Text.Json.Serialization;
8
8
  using Core.Extension;
9
+ using Core.Helper;
9
10
  using Core.Random;
10
11
  using Core.Serialization;
11
12
  using NUnit.Framework;
13
+ using UnityEngine;
12
14
 
13
15
  [DataContract]
14
16
  public sealed class TestDataObject
@@ -22,10 +24,73 @@
22
24
  public Dictionary<string, bool> DictionaryProperty { get; set; } = new();
23
25
 
24
26
  public List<int> ListProperty { get; set; } = new();
27
+
28
+ public List<Type> TypeProperties { get; set; } = new();
25
29
  }
26
30
 
27
- public class JsonSerializationTest
31
+ public sealed class JsonSerializationTest
28
32
  {
33
+ [Test]
34
+ public void UnityEngineObjectSerializationWorks()
35
+ {
36
+ GameObject testGo = new("Test GameObject", typeof(SpriteRenderer));
37
+ string json = testGo.ToJson();
38
+ Assert.IsFalse(string.IsNullOrWhiteSpace(json), json);
39
+ Assert.AreNotEqual("{}", json);
40
+ Assert.IsTrue(json.Contains("name = Test GameObject"), json);
41
+ Assert.IsTrue(json.Contains("type = UnityEngine.GameObject"), json);
42
+ }
43
+
44
+ [Test]
45
+ public void NullGameObjectSerializationWorks()
46
+ {
47
+ GameObject testGo = null;
48
+ string json = testGo.ToJson();
49
+ Assert.AreEqual("null", json);
50
+
51
+ testGo = new GameObject();
52
+ testGo.Destroy();
53
+ Assert.IsFalse(string.IsNullOrWhiteSpace(json), json);
54
+ Assert.AreEqual("null", json);
55
+ }
56
+
57
+ [Test]
58
+ public void TransformSerializationWorks()
59
+ {
60
+ GameObject testGo = new("Test GameObject", typeof(SpriteRenderer));
61
+ Transform transform = testGo.transform;
62
+ string json = transform.ToJson();
63
+ Assert.AreEqual("[]", json);
64
+ }
65
+
66
+ [Test]
67
+ public void ColorSerializationWorks()
68
+ {
69
+ Color color = new(0.5f, 0.5f, 0.5f, 0.5f);
70
+ string json = color.ToJson();
71
+ Color deserialized = Serializer.JsonDeserialize<Color>(json);
72
+ Assert.AreEqual(color, deserialized);
73
+
74
+ color = new Color(0.7f, 0.1f, 0.3f);
75
+ json = color.ToJson();
76
+ deserialized = Serializer.JsonDeserialize<Color>(json);
77
+ Assert.AreEqual(color, deserialized);
78
+ }
79
+
80
+ [Test]
81
+ public void Vector4SerializationWorks()
82
+ {
83
+ Vector4 vector = new(0.5f, 0.5f, 0.5f, 0.5f);
84
+ string json = vector.ToJson();
85
+ Vector4 deserialized = Serializer.JsonDeserialize<Vector4>(json);
86
+ Assert.AreEqual(vector, deserialized);
87
+
88
+ vector = new Vector4(0.7f, 0.1f, 0.3f);
89
+ json = vector.ToJson();
90
+ deserialized = Serializer.JsonDeserialize<Vector4>(json);
91
+ Assert.AreEqual(vector, deserialized);
92
+ }
93
+
29
94
  [Test]
30
95
  public void SerializationWorks()
31
96
  {
@@ -35,6 +100,12 @@
35
100
  field = Guid.NewGuid().ToString(),
36
101
  Property = random.Next(),
37
102
  NamedProperty = random.NextFloat(),
103
+ TypeProperties = new List<Type>()
104
+ {
105
+ typeof(int),
106
+ typeof(Serializer),
107
+ typeof(TestDataObject),
108
+ },
38
109
  };
39
110
 
40
111
  int dictionaryProperties = random.Next(4, 10);
@@ -79,6 +150,7 @@
79
150
  input.ListProperty.SequenceEqual(deserialized.ListProperty),
80
151
  $"Unexpected {nameof(deserialized.ListProperty)}! JSON: {json}"
81
152
  );
153
+ Assert.That(input.TypeProperties, Is.EquivalentTo(deserialized.TypeProperties));
82
154
  }
83
155
  }
84
156
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.unity-helpers",
3
- "version": "2.0.0-rc48",
3
+ "version": "2.0.0-rc50",
4
4
  "displayName": "Unity Helpers",
5
5
  "description": "Various Unity Helper Library",
6
6
  "dependencies": {},