com.wallstop-studios.unity-helpers 2.0.0-rc68 → 2.0.0-rc70

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 (74) hide show
  1. package/Editor/AnimationCopier.cs +875 -93
  2. package/Editor/AnimationCreator.cs +840 -137
  3. package/Editor/AnimationEventEditor.cs +4 -4
  4. package/Editor/AnimatorControllerCopier.cs +3 -3
  5. package/Editor/Extensions/UnityExtensions.cs +26 -0
  6. package/Editor/Extensions/UnityExtensions.cs.meta +3 -0
  7. package/Editor/Extensions.meta +3 -0
  8. package/Editor/FitTextureSizeWindow.cs +371 -0
  9. package/Editor/PrefabChecker.cs +716 -0
  10. package/Editor/SpriteAtlasGenerator.cs +598 -0
  11. package/Editor/SpriteAtlasGenerator.cs.meta +3 -0
  12. package/Editor/SpriteCropper.cs +407 -0
  13. package/Editor/SpriteCropper.cs.meta +3 -0
  14. package/Editor/SpriteSettingsApplier.cs +756 -92
  15. package/Editor/TextureResizerWizard.cs +3 -3
  16. package/Editor/TextureSettingsApplier.cs +9 -9
  17. package/Editor/WShowIfPropertyDrawer.cs +2 -2
  18. package/Runtime/Core/Attributes/EnumDisplayNameAttribute.cs +15 -0
  19. package/Runtime/Core/Attributes/EnumDisplayNameAttribute.cs.meta +3 -0
  20. package/Runtime/Core/Attributes/ValidateAssignmentAttribute.cs +1 -1
  21. package/Runtime/Core/Extension/EnumExtensions.cs +176 -1
  22. package/Runtime/Core/Extension/UnityExtensions.cs +1 -1
  23. package/Runtime/Core/Helper/Partials/LogHelpers.cs +1 -1
  24. package/Runtime/Core/Helper/Partials/MathHelpers.cs +1 -1
  25. package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +3 -4
  26. package/Runtime/Tags/Attribute.cs +205 -0
  27. package/Runtime/Tags/Attribute.cs.meta +3 -0
  28. package/Runtime/Tags/AttributeEffect.cs +276 -0
  29. package/Runtime/Tags/AttributeEffect.cs.meta +3 -0
  30. package/Runtime/Tags/AttributeModification.cs +51 -0
  31. package/Runtime/Tags/AttributeModification.cs.meta +3 -0
  32. package/Runtime/Tags/AttributeUtilities.cs +209 -0
  33. package/Runtime/Tags/AttributeUtilities.cs.meta +3 -0
  34. package/Runtime/Tags/AttributesComponent.cs +163 -0
  35. package/Runtime/Tags/AttributesComponent.cs.meta +3 -0
  36. package/Runtime/Tags/CosmeticEffectComponent.cs +50 -0
  37. package/Runtime/Tags/CosmeticEffectComponent.cs.meta +3 -0
  38. package/Runtime/Tags/CosmeticEffectData.cs +63 -0
  39. package/Runtime/Tags/CosmeticEffectData.cs.meta +3 -0
  40. package/Runtime/Tags/EffectHandle.cs +63 -0
  41. package/Runtime/Tags/EffectHandle.cs.meta +3 -0
  42. package/Runtime/Tags/EffectHandler.cs +380 -0
  43. package/Runtime/Tags/EffectHandler.cs.meta +3 -0
  44. package/Runtime/Tags/ModificationAction.cs +9 -0
  45. package/Runtime/Tags/ModificationAction.cs.meta +3 -0
  46. package/Runtime/Tags/ModifierDurationType.cs +13 -0
  47. package/Runtime/Tags/ModifierDurationType.cs.meta +3 -0
  48. package/Runtime/{Utils → Tags}/TagHandler.cs +42 -5
  49. package/Runtime/Tags.meta +3 -0
  50. package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs +1 -1
  51. package/Tests/Runtime/DataStructures/CyclicBufferTests.cs +1 -1
  52. package/Tests/Runtime/DataStructures/QuadTreeTests.cs +1 -1
  53. package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +1 -1
  54. package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs +1 -1
  55. package/Tests/Runtime/Extensions/DictionaryExtensionTests.cs +1 -1
  56. package/Tests/Runtime/Extensions/EnumExtensionTests.cs +1 -1
  57. package/Tests/Runtime/Extensions/IListExtensionTests.cs +1 -1
  58. package/Tests/Runtime/Extensions/LoggingExtensionTests.cs +1 -1
  59. package/Tests/Runtime/Extensions/RandomExtensionTests.cs +1 -1
  60. package/Tests/Runtime/Extensions/StringExtensionTests.cs +1 -1
  61. package/Tests/Runtime/Helper/ObjectHelperTests.cs +1 -0
  62. package/Tests/Runtime/Helper/WallMathTests.cs +1 -1
  63. package/Tests/Runtime/Performance/KDTreePerformanceTests.cs +1 -1
  64. package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs +1 -1
  65. package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +1 -1
  66. package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs +1 -1
  67. package/Tests/Runtime/Random/RandomTestBase.cs +2 -2
  68. package/Tests/Runtime/Serialization/JsonSerializationTest.cs +1 -1
  69. package/package.json +1 -1
  70. package/Editor/FitTextureSizeWizard.cs +0 -147
  71. package/Editor/PrefabCheckWizard.cs +0 -167
  72. /package/Editor/{FitTextureSizeWizard.cs.meta → FitTextureSizeWindow.cs.meta} +0 -0
  73. /package/Editor/{PrefabCheckWizard.cs.meta → PrefabChecker.cs.meta} +0 -0
  74. /package/Runtime/{Utils → Tags}/TagHandler.cs.meta +0 -0
@@ -9,8 +9,8 @@
9
9
  using UnityEditor;
10
10
  using UnityEngine;
11
11
  using UnityEngine.Serialization;
12
- using WallstopStudios.UnityHelpers.Core.Extension;
13
- using WallstopStudios.UnityHelpers.Core.Helper;
12
+ using Core.Extension;
13
+ using Core.Helper;
14
14
  using WallstopStudios.UnityHelpers.Utils;
15
15
  using Object = UnityEngine.Object;
16
16
 
@@ -39,7 +39,7 @@
39
39
  public float widthMultiplier = 0.54f;
40
40
  public float heightMultiplier = 0.245f;
41
41
 
42
- [MenuItem("Tools/Unity Helpers/Texture Resizer")]
42
+ [MenuItem("Tools/Wallstop Studios/Unity Helpers/Texture Resizer")]
43
43
  public static void ResizeTextures()
44
44
  {
45
45
  _ = DisplayWizard<TextureResizerWizard>("Texture Resizer", "Resize");
@@ -7,23 +7,23 @@
7
7
  using System.Linq;
8
8
  using UnityEditor;
9
9
  using UnityEngine;
10
- using WallstopStudios.UnityHelpers.Core.Attributes;
11
- using WallstopStudios.UnityHelpers.Core.Extension;
10
+ using Core.Attributes;
11
+ using Core.Extension;
12
12
  using WallstopStudios.UnityHelpers.Utils;
13
13
  using Object = UnityEngine.Object;
14
14
 
15
15
  public sealed class TextureSettingsApplier : ScriptableWizard
16
16
  {
17
- public bool applyReadOnly = false;
18
- public bool isReadOnly = false;
19
- public bool applyMipMaps = false;
20
- public bool generateMipMaps = false;
21
- public bool applyWrapMode = false;
17
+ public bool applyReadOnly;
18
+ public bool isReadOnly;
19
+ public bool applyMipMaps;
20
+ public bool generateMipMaps;
21
+ public bool applyWrapMode;
22
22
 
23
23
  [WShowIf(nameof(applyWrapMode))]
24
24
  public TextureWrapMode wrapMode = TextureWrapMode.Clamp;
25
25
 
26
- public bool applyFilterMode = false;
26
+ public bool applyFilterMode;
27
27
 
28
28
  [WShowIf(nameof(applyFilterMode))]
29
29
  public FilterMode filterMode = FilterMode.Trilinear;
@@ -42,7 +42,7 @@
42
42
  )]
43
43
  public List<Object> directories = new();
44
44
 
45
- [MenuItem("Tools/Unity Helpers/Texture Settings Applier")]
45
+ [MenuItem("Tools/Wallstop Studios/Unity Helpers/Texture Settings Applier")]
46
46
  public static void CreateAnimation()
47
47
  {
48
48
  _ = DisplayWizard<TextureSettingsApplier>("Texture Settings Directory Applier", "Set");
@@ -4,8 +4,8 @@
4
4
  using System.Reflection;
5
5
  using UnityEditor;
6
6
  using UnityEngine;
7
- using WallstopStudios.UnityHelpers.Core.Attributes;
8
- using WallstopStudios.UnityHelpers.Core.Extension;
7
+ using Core.Attributes;
8
+ using Core.Extension;
9
9
 
10
10
  [CustomPropertyDrawer(typeof(WShowIfAttribute))]
11
11
  public sealed class WShowIfPropertyDrawer : PropertyDrawer
@@ -0,0 +1,15 @@
1
+ namespace WallstopStudios.UnityHelpers.Core.Attributes
2
+ {
3
+ using System;
4
+
5
+ [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
6
+ public sealed class EnumDisplayNameAttribute : Attribute
7
+ {
8
+ public string DisplayName { get; }
9
+
10
+ public EnumDisplayNameAttribute(string displayName)
11
+ {
12
+ DisplayName = displayName;
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 54bb1abcfa114c6ba1e01504b66bc326
3
+ timeCreated: 1746457791
@@ -6,7 +6,7 @@
6
6
  using System.Linq;
7
7
  using System.Reflection;
8
8
  using Extension;
9
- using Helper.Partials;
9
+ using Helper;
10
10
  using JetBrains.Annotations;
11
11
  using Object = UnityEngine.Object;
12
12
 
@@ -1,7 +1,158 @@
1
- namespace WallstopStudios.UnityHelpers.Core.Extension
1
+ // ReSharper disable StaticMemberInGenericType
2
+ namespace WallstopStudios.UnityHelpers.Core.Extension
2
3
  {
3
4
  using System;
5
+ using System.Collections.Generic;
6
+ using System.Linq;
7
+ using System.Reflection;
4
8
  using System.Runtime.CompilerServices;
9
+ using Attributes;
10
+ using Helper;
11
+
12
+ public static class EnumNameCache<T>
13
+ where T : struct, Enum
14
+ {
15
+ private const int MaxDenseRange = 1024;
16
+
17
+ private static readonly bool UseDensePacking;
18
+ private static readonly int Min;
19
+ private static readonly string[]? DenseNames;
20
+ private static readonly Dictionary<int, string>? SparseNames;
21
+
22
+ static EnumNameCache()
23
+ {
24
+ T[] values = Enum.GetValues(typeof(T)).Cast<T>().ToArray();
25
+ int[] intValues = values.Select(v => Unsafe.As<T, int>(ref v)).ToArray();
26
+ int min = intValues.Min();
27
+ int max = intValues.Max();
28
+ int range = max - min + 1;
29
+
30
+ if (range <= MaxDenseRange)
31
+ {
32
+ UseDensePacking = true;
33
+ Min = min;
34
+ DenseNames = new string[range];
35
+
36
+ for (int i = 0; i < values.Length; i++)
37
+ {
38
+ int key = intValues[i] - min;
39
+ T value = values[i];
40
+ DenseNames[key] = value.ToString("G");
41
+ }
42
+ }
43
+ else
44
+ {
45
+ UseDensePacking = false;
46
+ SparseNames = new Dictionary<int, string>();
47
+ for (int i = 0; i < values.Length; i++)
48
+ {
49
+ int key = Unsafe.As<T, int>(ref values[i]);
50
+ T value = values[i];
51
+ string name = value.ToString("G");
52
+ SparseNames.TryAdd(key, name);
53
+ }
54
+ }
55
+ }
56
+
57
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
58
+ public static string ToCachedName(T value)
59
+ {
60
+ int key = Unsafe.As<T, int>(ref value);
61
+ if (UseDensePacking)
62
+ {
63
+ int idx = key - Min;
64
+ if ((uint)idx < (uint)DenseNames!.Length)
65
+ {
66
+ return DenseNames[idx];
67
+ }
68
+ }
69
+ else
70
+ {
71
+ if (SparseNames!.TryGetValue(key, out string name))
72
+ {
73
+ return name;
74
+ }
75
+ }
76
+
77
+ return value.ToString();
78
+ }
79
+ }
80
+
81
+ public static class EnumDisplayNameCache<T>
82
+ where T : struct, Enum
83
+ {
84
+ private const int MaxDenseRange = 1024;
85
+
86
+ private static readonly bool UseDensePacking;
87
+ private static readonly int Min;
88
+ private static readonly string[]? DenseNames;
89
+ private static readonly Dictionary<int, string>? SparseNames;
90
+
91
+ static EnumDisplayNameCache()
92
+ {
93
+ Type type = typeof(T);
94
+ FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Static);
95
+ T[] values = fields.Select(f => (T)f.GetValue(null)).ToArray();
96
+ int[] intValues = values.Select(v => Unsafe.As<T, int>(ref v)).ToArray();
97
+ int min = intValues.Min();
98
+ int max = intValues.Max();
99
+ int range = max - min + 1;
100
+
101
+ if (range <= MaxDenseRange)
102
+ {
103
+ UseDensePacking = true;
104
+ Min = min;
105
+ DenseNames = new string[range];
106
+
107
+ for (int i = 0; i < fields.Length; i++)
108
+ {
109
+ int key = intValues[i] - min;
110
+ FieldInfo field = fields[i];
111
+ string name = field.IsAttributeDefined(out EnumDisplayNameAttribute displayName)
112
+ ? displayName.DisplayName
113
+ : field.Name;
114
+ DenseNames[key] = name;
115
+ }
116
+ }
117
+ else
118
+ {
119
+ UseDensePacking = false;
120
+ SparseNames = new Dictionary<int, string>();
121
+ for (int i = 0; i < fields.Length; i++)
122
+ {
123
+ int key = Unsafe.As<T, int>(ref values[i]);
124
+ FieldInfo field = fields[i];
125
+ string name = field.IsAttributeDefined(out EnumDisplayNameAttribute displayName)
126
+ ? displayName.DisplayName
127
+ : field.Name;
128
+ SparseNames.TryAdd(key, name);
129
+ }
130
+ }
131
+ }
132
+
133
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
134
+ public static string ToDisplayName(T value)
135
+ {
136
+ int key = Unsafe.As<T, int>(ref value);
137
+ if (UseDensePacking)
138
+ {
139
+ int idx = key - Min;
140
+ if ((uint)idx < (uint)DenseNames!.Length)
141
+ {
142
+ return DenseNames[idx];
143
+ }
144
+ }
145
+ else
146
+ {
147
+ if (SparseNames!.TryGetValue(key, out string name))
148
+ {
149
+ return name;
150
+ }
151
+ }
152
+
153
+ return value.ToString();
154
+ }
155
+ }
5
156
 
6
157
  public static class EnumExtensions
7
158
  {
@@ -14,6 +165,30 @@
14
165
  return (valueUnderlying & flagUnderlying) == flagUnderlying;
15
166
  }
16
167
 
168
+ public static string ToDisplayName<T>(this T value)
169
+ where T : unmanaged, Enum
170
+ {
171
+ return EnumDisplayNameCache<T>.ToDisplayName(value);
172
+ }
173
+
174
+ public static IEnumerable<string> ToDisplayNames<T>(this IEnumerable<T> enumerable)
175
+ where T : unmanaged, Enum
176
+ {
177
+ return enumerable.Select(value => value.ToDisplayName());
178
+ }
179
+
180
+ public static string ToCachedName<T>(this T value)
181
+ where T : unmanaged, Enum
182
+ {
183
+ return EnumNameCache<T>.ToCachedName(value);
184
+ }
185
+
186
+ public static IEnumerable<string> ToCachedNames<T>(this IEnumerable<T> enumerable)
187
+ where T : unmanaged, Enum
188
+ {
189
+ return enumerable.Select(value => value.ToCachedName());
190
+ }
191
+
17
192
  [MethodImpl(MethodImplOptions.AggressiveInlining)]
18
193
  private static unsafe ulong GetUInt64<T>(T value)
19
194
  where T : unmanaged
@@ -1508,7 +1508,7 @@
1508
1508
  );
1509
1509
  }
1510
1510
 
1511
- public static void SetColors(this UnityEngine.UI.Slider slider, Color color)
1511
+ public static void SetColors(this Slider slider, Color color)
1512
1512
  {
1513
1513
  ColorBlock block = slider.colors;
1514
1514
 
@@ -1,4 +1,4 @@
1
- namespace WallstopStudios.UnityHelpers.Core.Helper.Partials
1
+ namespace WallstopStudios.UnityHelpers.Core.Helper
2
2
  {
3
3
  using Extension;
4
4
  using UnityEngine;
@@ -1,4 +1,4 @@
1
- namespace WallstopStudios.UnityHelpers.Core.Helper.Partials
1
+ namespace WallstopStudios.UnityHelpers.Core.Helper
2
2
  {
3
3
  using UnityEngine;
4
4
 
@@ -2,13 +2,12 @@
2
2
  {
3
3
  using System;
4
4
  using Extension;
5
+ using UnityEditor;
6
+ using UnityEditor.SceneManagement;
5
7
  using UnityEngine;
6
8
  using UnityEngine.SceneManagement;
7
9
  using Object = UnityEngine.Object;
8
- #if UNITY_EDITOR
9
- using UnityEditor;
10
- using UnityEditor.SceneManagement;
11
- #endif
10
+
12
11
  public static partial class Helpers
13
12
  {
14
13
  public static T Find<T>(this Object component, string tag, bool log = true)
@@ -0,0 +1,205 @@
1
+ namespace WallstopStudios.UnityHelpers.Tags
2
+ {
3
+ using System;
4
+ using System.Collections.Generic;
5
+ using System.ComponentModel;
6
+ using System.Globalization;
7
+ using System.Linq;
8
+ using System.Runtime.Serialization;
9
+ using System.Text.Json.Serialization;
10
+ using Core.Extension;
11
+ using ProtoBuf;
12
+ using UnityEngine;
13
+
14
+ [Serializable]
15
+ [ProtoContract]
16
+ public sealed class Attribute : IEquatable<Attribute>, IEquatable<float>
17
+ {
18
+ public float CurrentValue
19
+ {
20
+ get
21
+ {
22
+ #if UNITY_EDITOR
23
+ /*
24
+ For some reason, there's a bug with loot tables where
25
+ _currentValueCalculated will be true but the current
26
+ value is not calculated, so ignore the flag if we're
27
+ in editor mode, where this happens
28
+ */
29
+ if (Application.isPlaying)
30
+ #endif
31
+ {
32
+ if (_currentValueCalculated)
33
+ {
34
+ return _currentValue;
35
+ }
36
+ }
37
+
38
+ CalculateCurrentValue();
39
+ return _currentValue;
40
+ }
41
+ }
42
+
43
+ public float BaseValue => _baseValue;
44
+
45
+ [SerializeField]
46
+ internal float _baseValue;
47
+
48
+ [SerializeField]
49
+ private float _currentValue;
50
+
51
+ private bool _currentValueCalculated;
52
+
53
+ internal void CalculateCurrentValue()
54
+ {
55
+ float calculatedValue = _baseValue;
56
+ foreach (
57
+ AttributeModification attributeModification in _modifications
58
+ .SelectMany(kvp => kvp.Value)
59
+ .OrderBy(mod => mod.action)
60
+ )
61
+ {
62
+ ApplyAttributeModification(attributeModification, ref calculatedValue);
63
+ }
64
+
65
+ _currentValue = calculatedValue;
66
+ _currentValueCalculated = true;
67
+ }
68
+
69
+ private readonly Dictionary<EffectHandle, List<AttributeModification>> _modifications =
70
+ new();
71
+
72
+ public static implicit operator float(Attribute attribute) => attribute.CurrentValue;
73
+
74
+ public static implicit operator Attribute(float value) => new(value);
75
+
76
+ public Attribute()
77
+ : this(0) { }
78
+
79
+ public Attribute(float value)
80
+ {
81
+ _baseValue = value;
82
+ _currentValueCalculated = false;
83
+ }
84
+
85
+ [JsonConstructor]
86
+ public Attribute(float baseValue, float currentValue)
87
+ {
88
+ _baseValue = baseValue;
89
+ _currentValue = currentValue;
90
+ _currentValueCalculated = true;
91
+ }
92
+
93
+ public void ClearCache()
94
+ {
95
+ _currentValueCalculated = false;
96
+ }
97
+
98
+ public void ApplyAttributeModification(
99
+ AttributeModification attributeModification,
100
+ EffectHandle? handle = null
101
+ )
102
+ {
103
+ // If we don't have a handle, then this is an instant effect, apply it to the base value.
104
+ if (!handle.HasValue)
105
+ {
106
+ ApplyAttributeModification(attributeModification, ref _baseValue);
107
+ }
108
+ else
109
+ {
110
+ _modifications.GetOrAdd(handle.Value).Add(attributeModification);
111
+ }
112
+
113
+ CalculateCurrentValue();
114
+ }
115
+
116
+ public bool RemoveAttributeModification(EffectHandle handle)
117
+ {
118
+ bool removed = _modifications.Remove(handle);
119
+ if (removed)
120
+ {
121
+ CalculateCurrentValue();
122
+ }
123
+
124
+ return removed;
125
+ }
126
+
127
+ [OnDeserialized]
128
+ private void AfterDeserialize(StreamingContext streamingContext)
129
+ {
130
+ ClearCache();
131
+ }
132
+
133
+ [ProtoAfterDeserialization]
134
+ private void AfterProtoDeserialized()
135
+ {
136
+ ClearCache();
137
+ }
138
+
139
+ private static void ApplyAttributeModification(
140
+ AttributeModification attributeModification,
141
+ ref float value
142
+ )
143
+ {
144
+ switch (attributeModification.action)
145
+ {
146
+ case ModificationAction.Addition:
147
+ value += attributeModification.value;
148
+ break;
149
+ case ModificationAction.Multiplication:
150
+ value *= attributeModification.value;
151
+ break;
152
+ case ModificationAction.Override:
153
+ value = attributeModification.value;
154
+ break;
155
+ default:
156
+ throw new InvalidEnumArgumentException(
157
+ nameof(attributeModification.action),
158
+ (int)attributeModification.action,
159
+ typeof(ModificationAction)
160
+ );
161
+ }
162
+ }
163
+
164
+ public bool Equals(Attribute other)
165
+ {
166
+ if (ReferenceEquals(this, other))
167
+ {
168
+ return true;
169
+ }
170
+
171
+ return other != null && CurrentValue.Equals(other.CurrentValue);
172
+ }
173
+
174
+ public override bool Equals(object other)
175
+ {
176
+ switch (other)
177
+ {
178
+ case Attribute attribute:
179
+ return Equals(attribute);
180
+ case float attribute:
181
+ return Equals(attribute);
182
+ case double attribute:
183
+ return Equals((float)attribute);
184
+ default:
185
+ return false;
186
+ }
187
+ }
188
+
189
+ public bool Equals(float other)
190
+ {
191
+ return CurrentValue.Equals(other);
192
+ }
193
+
194
+ public override int GetHashCode()
195
+ {
196
+ // ReSharper disable once BaseObjectGetHashCodeCallInGetHashCode
197
+ return base.GetHashCode();
198
+ }
199
+
200
+ public override string ToString()
201
+ {
202
+ return ((float)this).ToString(CultureInfo.InvariantCulture);
203
+ }
204
+ }
205
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 7209237176394eaf99a875c53950e2d0
3
+ timeCreated: 1746412136