com.wallstop-studios.unity-helpers 2.0.0-rc12 → 2.0.0-rc14

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.
Files changed (37) hide show
  1. package/Editor/EnsureTextureSizeWizard.cs +110 -0
  2. package/Editor/EnsureTextureSizeWizard.cs.meta +3 -0
  3. package/Runtime/Core/Attributes/ChildComponentAttribute.cs +124 -31
  4. package/Runtime/Core/Attributes/ParentComponent.cs +119 -29
  5. package/Runtime/Core/Attributes/SiblingComponentAttribute.cs +31 -12
  6. package/Runtime/Core/Extension/ColorExtensions.cs +260 -1
  7. package/Runtime/Core/Extension/UnityExtensions.cs +10 -0
  8. package/Runtime/Core/Helper/Geometry.cs +17 -0
  9. package/Runtime/Core/Helper/SpriteHelpers.cs +36 -3
  10. package/Runtime/Core/Random/PcgRandom.cs +2 -2
  11. package/Runtime/Core/Random/RomuDuo.cs +116 -0
  12. package/Runtime/Core/Random/RomuDuo.cs.meta +3 -0
  13. package/Runtime/Core/Random/SplitMix64.cs +94 -0
  14. package/Runtime/Core/Random/SplitMix64.cs.meta +3 -0
  15. package/Runtime/Core/Random/XorShiroRandom.cs +117 -0
  16. package/Runtime/Core/Random/XorShiroRandom.cs.meta +3 -0
  17. package/Runtime/UI/LayeredImage.cs +364 -0
  18. package/Runtime/UI/LayeredImage.cs.meta +3 -0
  19. package/Runtime/UI.meta +3 -0
  20. package/Tests/Runtime/Attributes/ChildComponentTests.cs +81 -0
  21. package/Tests/Runtime/Attributes/ChildComponentTests.cs.meta +3 -0
  22. package/Tests/Runtime/Attributes/Components/ExpectChildSpriteRenderers.cs +28 -0
  23. package/Tests/Runtime/Attributes/Components/ExpectChildSpriteRenderers.cs.meta +3 -0
  24. package/Tests/Runtime/Attributes/Components/ExpectParentSpriteRenderers.cs +28 -0
  25. package/Tests/Runtime/Attributes/Components/ExpectParentSpriteRenderers.cs.meta +3 -0
  26. package/Tests/Runtime/Attributes/Components.meta +3 -0
  27. package/Tests/Runtime/Attributes/ParentComponentTests.cs +68 -0
  28. package/Tests/Runtime/Attributes/ParentComponentTests.cs.meta +3 -0
  29. package/Tests/Runtime/Attributes.meta +3 -0
  30. package/Tests/Runtime/Performance/RandomPerformanceTests.cs +3 -0
  31. package/Tests/Runtime/Random/RomuDuoRandomTests.cs +9 -0
  32. package/Tests/Runtime/Random/RomuDuoRandomTests.cs.meta +3 -0
  33. package/Tests/Runtime/Random/SplitMix64RandomTests.cs +9 -0
  34. package/Tests/Runtime/Random/SplitMix64RandomTests.cs.meta +3 -0
  35. package/Tests/Runtime/Random/XorShiroRandomTests.cs +9 -0
  36. package/Tests/Runtime/Random/XorShiroRandomTests.cs.meta +3 -0
  37. package/package.json +1 -1
@@ -0,0 +1,110 @@
1
+ namespace UnityHelpers.Editor
2
+ {
3
+ using System.Collections.Generic;
4
+ using System.Linq;
5
+ using Core.Extension;
6
+ using UnityEditor;
7
+ using UnityEngine;
8
+
9
+ public sealed class EnsureTextureSizeWizard : ScriptableWizard
10
+ {
11
+ public List<Texture2D> textures = new();
12
+
13
+ public List<Object> textureSourcePaths = new();
14
+
15
+ [MenuItem("Tools/Unity Helpers/Ensure Texture Size")]
16
+ public static void EnsureSizes()
17
+ {
18
+ _ = DisplayWizard<EnsureTextureSizeWizard>("Ensure Texture Size", "Run");
19
+ }
20
+
21
+ private void OnWizardCreate()
22
+ {
23
+ textures ??= new List<Texture2D>();
24
+ textureSourcePaths ??= new List<Object>();
25
+ HashSet<string> texturePath = new();
26
+ foreach (Object textureSource in textureSourcePaths)
27
+ {
28
+ string assetPath = AssetDatabase.GetAssetPath(textureSource);
29
+ if (!string.IsNullOrWhiteSpace(assetPath))
30
+ {
31
+ _ = texturePath.Add(assetPath);
32
+ }
33
+ }
34
+
35
+ if (texturePath.Any())
36
+ {
37
+ foreach (
38
+ string assetGuid in AssetDatabase.FindAssets(
39
+ "t:texture2D",
40
+ texturePath.ToArray()
41
+ )
42
+ )
43
+ {
44
+ string path = AssetDatabase.GUIDToAssetPath(assetGuid);
45
+ if (string.IsNullOrWhiteSpace(path))
46
+ {
47
+ continue;
48
+ }
49
+
50
+ Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
51
+ if (texture != null)
52
+ {
53
+ textures.Add(texture);
54
+ }
55
+ }
56
+ }
57
+
58
+ textures = textures.Distinct().OrderBy(texture => texture.name).ToList();
59
+ if (textures.Count <= 0)
60
+ {
61
+ this.Log("Failed to find any texture paths.");
62
+ return;
63
+ }
64
+
65
+ int changedCount = 0;
66
+ foreach (Texture2D inputTexture in textures)
67
+ {
68
+ Texture2D texture = inputTexture;
69
+ string assetPath = AssetDatabase.GetAssetPath(texture);
70
+ if (string.IsNullOrWhiteSpace(assetPath))
71
+ {
72
+ continue;
73
+ }
74
+
75
+ TextureImporter tImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
76
+ if (tImporter == null)
77
+ {
78
+ continue;
79
+ }
80
+ tImporter.GetSourceTextureWidthAndHeight(out int width, out int height);
81
+
82
+ float size = Mathf.Max(width, height);
83
+ int textureSize = tImporter.maxTextureSize;
84
+ bool changed = false;
85
+ while (textureSize < size)
86
+ {
87
+ changed = true;
88
+ textureSize <<= 1;
89
+ }
90
+ tImporter.maxTextureSize = textureSize;
91
+
92
+ if (changed)
93
+ {
94
+ changedCount++;
95
+ tImporter.SaveAndReimport();
96
+ }
97
+ }
98
+
99
+ if (changedCount != 0)
100
+ {
101
+ this.Log($"Updated {changedCount} textures.");
102
+ AssetDatabase.Refresh();
103
+ }
104
+ else
105
+ {
106
+ this.Log("No textures updated.");
107
+ }
108
+ }
109
+ }
110
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 8e55e0cc59d640b3affc8f4d9f865c50
3
+ timeCreated: 1735605040
@@ -6,6 +6,7 @@
6
6
  using System.Linq;
7
7
  using System.Reflection;
8
8
  using Extension;
9
+ using Helper;
9
10
  using JetBrains.Annotations;
10
11
  using UnityEngine;
11
12
 
@@ -14,6 +15,7 @@
14
15
  public sealed class ChildComponentAttribute : Attribute
15
16
  {
16
17
  public bool optional = false;
18
+ public bool onlyDescendents = false;
17
19
  }
18
20
 
19
21
  public static class ChildComponentExtensions
@@ -24,14 +26,17 @@
24
26
  {
25
27
  Type componentType = component.GetType();
26
28
  FieldInfo[] fields = FieldsByType.GetOrAdd(
27
- componentType, type =>
29
+ componentType,
30
+ type =>
28
31
  {
29
32
  FieldInfo[] fields = type.GetFields(
30
- BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
33
+ BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
34
+ );
31
35
  return fields
32
- .Where(prop => Attribute.IsDefined(prop, typeof(ChildComponentAttribute)))
36
+ .Where(field => Attribute.IsDefined(field, typeof(ChildComponentAttribute)))
33
37
  .ToArray();
34
- });
38
+ }
39
+ );
35
40
 
36
41
  foreach (FieldInfo field in fields)
37
42
  {
@@ -40,46 +45,134 @@
40
45
  Type childComponentType = isArray ? fieldType.GetElementType() : fieldType;
41
46
 
42
47
  bool foundChild;
43
- if (isArray)
48
+ if (field.GetCustomAttribute<ChildComponentAttribute>().onlyDescendents)
44
49
  {
45
- Component[] childComponents = component.GetComponentsInChildren(childComponentType, true);
46
- foundChild = 0 < childComponents.Length;
50
+ if (isArray)
51
+ {
52
+ List<Component> children = new();
53
+ foreach (Transform child in component.IterateOverAllChildren())
54
+ {
55
+ children.AddRange(
56
+ child.GetComponentsInChildren(childComponentType, true)
57
+ );
58
+ }
47
59
 
48
- Array correctTypedArray = Array.CreateInstance(childComponentType, childComponents.Length);
49
- Array.Copy(childComponents, correctTypedArray, childComponents.Length);
50
- field.SetValue(component, correctTypedArray);
51
- }
52
- else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(List<>))
53
- {
54
- childComponentType = fieldType.GenericTypeArguments[0];
55
- Type constructedListType = typeof(List<>).MakeGenericType(childComponentType);
56
- IList instance = (IList)Activator.CreateInstance(constructedListType);
60
+ foundChild = 0 < children.Count;
57
61
 
58
- foundChild = false;
59
- foreach (Component childComponent in component.GetComponentsInChildren(childComponentType, true))
60
- {
61
- instance.Add(childComponent);
62
- foundChild = true;
62
+ Array correctTypedArray = Array.CreateInstance(
63
+ childComponentType,
64
+ children.Count
65
+ );
66
+ Array.Copy(children.ToArray(), correctTypedArray, children.Count);
67
+ field.SetValue(component, correctTypedArray);
63
68
  }
69
+ else if (
70
+ fieldType.IsGenericType
71
+ && fieldType.GetGenericTypeDefinition() == typeof(List<>)
72
+ )
73
+ {
74
+ childComponentType = fieldType.GenericTypeArguments[0];
75
+ Type constructedListType = typeof(List<>).MakeGenericType(
76
+ childComponentType
77
+ );
78
+ IList instance = (IList)Activator.CreateInstance(constructedListType);
79
+
80
+ foundChild = false;
81
+ foreach (
82
+ Component childComponent in component
83
+ .IterateOverAllChildren()
84
+ .SelectMany(child =>
85
+ child.GetComponentsInChildren(childComponentType, true)
86
+ )
87
+ )
88
+ {
89
+ instance.Add(childComponent);
90
+ foundChild = true;
91
+ }
64
92
 
65
- field.SetValue(component, instance);
93
+ field.SetValue(component, instance);
94
+ }
95
+ else
96
+ {
97
+ foundChild = false;
98
+ Component childComponent = null;
99
+ foreach (Transform child in component.IterateOverAllChildren())
100
+ {
101
+ childComponent = child.GetComponent(childComponentType);
102
+ if (childComponent != null)
103
+ {
104
+ foundChild = true;
105
+ break;
106
+ }
107
+ }
108
+ if (foundChild)
109
+ {
110
+ field.SetValue(component, childComponent);
111
+ }
112
+ }
66
113
  }
67
114
  else
68
115
  {
69
- Component childComponent = component.GetComponentInChildren(childComponentType, true);
70
- foundChild = childComponent != null;
71
- if (foundChild)
116
+ if (isArray)
117
+ {
118
+ Component[] childComponents = component.GetComponentsInChildren(
119
+ childComponentType,
120
+ true
121
+ );
122
+ foundChild = 0 < childComponents.Length;
123
+
124
+ Array correctTypedArray = Array.CreateInstance(
125
+ childComponentType,
126
+ childComponents.Length
127
+ );
128
+ Array.Copy(childComponents, correctTypedArray, childComponents.Length);
129
+ field.SetValue(component, correctTypedArray);
130
+ }
131
+ else if (
132
+ fieldType.IsGenericType
133
+ && fieldType.GetGenericTypeDefinition() == typeof(List<>)
134
+ )
135
+ {
136
+ childComponentType = fieldType.GenericTypeArguments[0];
137
+ Type constructedListType = typeof(List<>).MakeGenericType(
138
+ childComponentType
139
+ );
140
+ IList instance = (IList)Activator.CreateInstance(constructedListType);
141
+
142
+ foundChild = false;
143
+ foreach (
144
+ Component childComponent in component.GetComponentsInChildren(
145
+ childComponentType,
146
+ true
147
+ )
148
+ )
149
+ {
150
+ instance.Add(childComponent);
151
+ foundChild = true;
152
+ }
153
+
154
+ field.SetValue(component, instance);
155
+ }
156
+ else
72
157
  {
73
- field.SetValue(component, childComponent);
158
+ Component childComponent = component.GetComponentInChildren(
159
+ childComponentType,
160
+ true
161
+ );
162
+ foundChild = childComponent != null;
163
+ if (foundChild)
164
+ {
165
+ field.SetValue(component, childComponent);
166
+ }
74
167
  }
75
168
  }
76
169
 
77
170
  if (!foundChild)
78
171
  {
79
- if (field.GetCustomAttributes(typeof(ChildComponentAttribute), false)[0] is ChildComponentAttribute
80
- {
81
- optional: false
82
- } _)
172
+ if (
173
+ field.GetCustomAttributes(typeof(ChildComponentAttribute), false)[0]
174
+ is ChildComponentAttribute { optional: false } _
175
+ )
83
176
  {
84
177
  component.LogError($"Unable to find child component of type {fieldType}");
85
178
  }
@@ -87,4 +180,4 @@
87
180
  }
88
181
  }
89
182
  }
90
- }
183
+ }
@@ -14,6 +14,7 @@
14
14
  public sealed class ParentComponentAttribute : Attribute
15
15
  {
16
16
  public bool optional = false;
17
+ public bool onlyAncestors = false;
17
18
  }
18
19
 
19
20
  public static class ParentComponentExtensions
@@ -24,14 +25,19 @@
24
25
  {
25
26
  Type componentType = component.GetType();
26
27
  FieldInfo[] fields = FieldsByType.GetOrAdd(
27
- componentType, type =>
28
+ componentType,
29
+ type =>
28
30
  {
29
31
  FieldInfo[] fields = type.GetFields(
30
- BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
32
+ BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
33
+ );
31
34
  return fields
32
- .Where(prop => Attribute.IsDefined(prop, typeof(ParentComponentAttribute)))
35
+ .Where(field =>
36
+ Attribute.IsDefined(field, typeof(ParentComponentAttribute))
37
+ )
33
38
  .ToArray();
34
- });
39
+ }
40
+ );
35
41
 
36
42
  foreach (FieldInfo field in fields)
37
43
  {
@@ -40,44 +46,128 @@
40
46
  Type parentComponentType = isArray ? fieldType.GetElementType() : fieldType;
41
47
 
42
48
  bool foundParent;
43
- if (isArray)
49
+ if (field.GetCustomAttribute<ParentComponentAttribute>().onlyAncestors)
44
50
  {
45
- Component[] parentComponents = component.GetComponentsInParent(parentComponentType, true);
46
- foundParent = 0 < parentComponents.Length;
51
+ Transform parent = component.transform.parent;
52
+ if (parent == null)
53
+ {
54
+ foundParent = false;
55
+ }
56
+ else if (isArray)
57
+ {
58
+ Component[] parentComponents = parent.GetComponentsInParent(
59
+ parentComponentType,
60
+ true
61
+ );
62
+ foundParent = 0 < parentComponents.Length;
47
63
 
48
- Array correctTypedArray = Array.CreateInstance(parentComponentType, parentComponents.Length);
49
- Array.Copy(parentComponents, correctTypedArray, parentComponents.Length);
50
- field.SetValue(component, correctTypedArray);
51
- }
52
- else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(List<>))
53
- {
54
- parentComponentType = fieldType.GenericTypeArguments[0];
55
- Type constructedListType = typeof(List<>).MakeGenericType(parentComponentType);
56
- IList instance = (IList)Activator.CreateInstance(constructedListType);
64
+ Array correctTypedArray = Array.CreateInstance(
65
+ parentComponentType,
66
+ parentComponents.Length
67
+ );
68
+ Array.Copy(parentComponents, correctTypedArray, parentComponents.Length);
69
+ field.SetValue(component, correctTypedArray);
70
+ }
71
+ else if (
72
+ fieldType.IsGenericType
73
+ && fieldType.GetGenericTypeDefinition() == typeof(List<>)
74
+ )
75
+ {
76
+ parentComponentType = fieldType.GenericTypeArguments[0];
77
+ Type constructedListType = typeof(List<>).MakeGenericType(
78
+ parentComponentType
79
+ );
80
+ IList instance = (IList)Activator.CreateInstance(constructedListType);
81
+
82
+ foundParent = false;
83
+ foreach (
84
+ Component parentComponent in parent.GetComponentsInParent(
85
+ parentComponentType,
86
+ true
87
+ )
88
+ )
89
+ {
90
+ instance.Add(parentComponent);
91
+ foundParent = true;
92
+ }
57
93
 
58
- foundParent = false;
59
- foreach (Component parentComponent in component.GetComponentsInParent(parentComponentType, true))
94
+ field.SetValue(component, instance);
95
+ }
96
+ else
60
97
  {
61
- instance.Add(parentComponent);
62
- foundParent = true;
98
+ Component childComponent = parent.GetComponentInParent(
99
+ parentComponentType,
100
+ true
101
+ );
102
+ foundParent = childComponent != null;
103
+ if (foundParent)
104
+ {
105
+ field.SetValue(component, childComponent);
106
+ }
63
107
  }
64
-
65
- field.SetValue(component, instance);
66
108
  }
67
109
  else
68
110
  {
69
- Component childComponent = component.GetComponentInParent(parentComponentType, true);
70
- foundParent = childComponent != null;
71
- if (foundParent)
111
+ if (isArray)
112
+ {
113
+ Component[] parentComponents = component.GetComponentsInParent(
114
+ parentComponentType,
115
+ true
116
+ );
117
+ foundParent = 0 < parentComponents.Length;
118
+
119
+ Array correctTypedArray = Array.CreateInstance(
120
+ parentComponentType,
121
+ parentComponents.Length
122
+ );
123
+ Array.Copy(parentComponents, correctTypedArray, parentComponents.Length);
124
+ field.SetValue(component, correctTypedArray);
125
+ }
126
+ else if (
127
+ fieldType.IsGenericType
128
+ && fieldType.GetGenericTypeDefinition() == typeof(List<>)
129
+ )
130
+ {
131
+ parentComponentType = fieldType.GenericTypeArguments[0];
132
+ Type constructedListType = typeof(List<>).MakeGenericType(
133
+ parentComponentType
134
+ );
135
+ IList instance = (IList)Activator.CreateInstance(constructedListType);
136
+
137
+ foundParent = false;
138
+ foreach (
139
+ Component parentComponent in component.GetComponentsInParent(
140
+ parentComponentType,
141
+ true
142
+ )
143
+ )
144
+ {
145
+ instance.Add(parentComponent);
146
+ foundParent = true;
147
+ }
148
+
149
+ field.SetValue(component, instance);
150
+ }
151
+ else
72
152
  {
73
- field.SetValue(component, childComponent);
153
+ Component childComponent = component.GetComponentInParent(
154
+ parentComponentType,
155
+ true
156
+ );
157
+ foundParent = childComponent != null;
158
+ if (foundParent)
159
+ {
160
+ field.SetValue(component, childComponent);
161
+ }
74
162
  }
75
163
  }
76
164
 
77
165
  if (!foundParent)
78
166
  {
79
- if (field.GetCustomAttributes(typeof(ParentComponentAttribute), false)[0] is
80
- ParentComponentAttribute { optional: false } _)
167
+ if (
168
+ field.GetCustomAttributes(typeof(ParentComponentAttribute), false)[0]
169
+ is ParentComponentAttribute { optional: false } _
170
+ )
81
171
  {
82
172
  component.LogError($"Unable to find parent component of type {fieldType}");
83
173
  }
@@ -85,4 +175,4 @@
85
175
  }
86
176
  }
87
177
  }
88
- }
178
+ }
@@ -1,12 +1,12 @@
1
1
  namespace UnityHelpers.Core.Attributes
2
2
  {
3
- using Extension;
4
- using JetBrains.Annotations;
5
3
  using System;
6
4
  using System.Collections;
7
5
  using System.Collections.Generic;
8
6
  using System.Linq;
9
7
  using System.Reflection;
8
+ using Extension;
9
+ using JetBrains.Annotations;
10
10
  using UnityEngine;
11
11
 
12
12
  [AttributeUsage(AttributeTargets.Field)]
@@ -28,11 +28,15 @@
28
28
  type =>
29
29
  {
30
30
  FieldInfo[] fields = type.GetFields(
31
- BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
31
+ BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
32
+ );
32
33
  return fields
33
- .Where(prop => Attribute.IsDefined(prop, typeof(SiblingComponentAttribute)))
34
+ .Where(field =>
35
+ Attribute.IsDefined(field, typeof(SiblingComponentAttribute))
36
+ )
34
37
  .ToArray();
35
- });
38
+ }
39
+ );
36
40
 
37
41
  foreach (FieldInfo field in fields)
38
42
  {
@@ -46,18 +50,26 @@
46
50
  Component[] siblingComponents = component.GetComponents(siblingComponentType);
47
51
  foundSibling = 0 < siblingComponents.Length;
48
52
 
49
- Array correctTypedArray = Array.CreateInstance(siblingComponentType, siblingComponents.Length);
53
+ Array correctTypedArray = Array.CreateInstance(
54
+ siblingComponentType,
55
+ siblingComponents.Length
56
+ );
50
57
  Array.Copy(siblingComponents, correctTypedArray, siblingComponents.Length);
51
58
  field.SetValue(component, correctTypedArray);
52
59
  }
53
- else if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition() == typeof(List<>))
60
+ else if (
61
+ fieldType.IsGenericType
62
+ && fieldType.GetGenericTypeDefinition() == typeof(List<>)
63
+ )
54
64
  {
55
65
  siblingComponentType = fieldType.GenericTypeArguments[0];
56
66
  Type constructedListType = typeof(List<>).MakeGenericType(siblingComponentType);
57
67
  IList instance = (IList)Activator.CreateInstance(constructedListType);
58
68
 
59
69
  foundSibling = false;
60
- foreach (Component siblingComponent in component.GetComponents(siblingComponentType))
70
+ foreach (
71
+ Component siblingComponent in component.GetComponents(siblingComponentType)
72
+ )
61
73
  {
62
74
  instance.Add(siblingComponent);
63
75
  foundSibling = true;
@@ -67,7 +79,12 @@
67
79
  }
68
80
  else
69
81
  {
70
- if (component.TryGetComponent(siblingComponentType, out Component siblingComponent))
82
+ if (
83
+ component.TryGetComponent(
84
+ siblingComponentType,
85
+ out Component siblingComponent
86
+ )
87
+ )
71
88
  {
72
89
  foundSibling = true;
73
90
  field.SetValue(component, siblingComponent);
@@ -80,8 +97,10 @@
80
97
 
81
98
  if (!foundSibling)
82
99
  {
83
- if (field.GetCustomAttributes(typeof(SiblingComponentAttribute), false)[0] is
84
- SiblingComponentAttribute { optional: false } _)
100
+ if (
101
+ field.GetCustomAttributes(typeof(SiblingComponentAttribute), false)[0]
102
+ is SiblingComponentAttribute { optional: false } _
103
+ )
85
104
  {
86
105
  component.LogError($"Unable to find sibling component of type {fieldType}");
87
106
  }
@@ -89,4 +108,4 @@
89
108
  }
90
109
  }
91
110
  }
92
- }
111
+ }