com.wallstop-studios.unity-helpers 2.0.3 → 2.1.0

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 (58) hide show
  1. package/Docs/DATA_STRUCTURES.md +7 -7
  2. package/Docs/EFFECTS_SYSTEM.md +836 -8
  3. package/Docs/EFFECTS_SYSTEM_TUTORIAL.md +77 -18
  4. package/Docs/HULLS.md +2 -2
  5. package/Docs/RANDOM_PERFORMANCE.md +1 -1
  6. package/Docs/REFLECTION_HELPERS.md +1 -1
  7. package/Docs/RELATIONAL_COMPONENTS.md +51 -6
  8. package/Docs/SERIALIZATION.md +1 -1
  9. package/Docs/SINGLETONS.md +2 -2
  10. package/Docs/SPATIAL_TREES_2D_GUIDE.md +3 -3
  11. package/Docs/SPATIAL_TREES_3D_GUIDE.md +3 -3
  12. package/Docs/SPATIAL_TREE_SEMANTICS.md +7 -7
  13. package/Editor/CustomDrawers/WShowIfPropertyDrawer.cs +131 -41
  14. package/Editor/Utils/ScriptableObjectSingletonCreator.cs +175 -18
  15. package/README.md +17 -3
  16. package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs +4 -2
  17. package/Runtime/Tags/Attribute.cs +144 -24
  18. package/Runtime/Tags/AttributeEffect.cs +278 -11
  19. package/Runtime/Tags/AttributeModification.cs +59 -29
  20. package/Runtime/Tags/AttributeUtilities.cs +465 -0
  21. package/Runtime/Tags/AttributesComponent.cs +20 -0
  22. package/Runtime/Tags/EffectBehavior.cs +171 -0
  23. package/Runtime/Tags/EffectBehavior.cs.meta +4 -0
  24. package/Runtime/Tags/EffectHandle.cs +5 -0
  25. package/Runtime/Tags/EffectHandler.cs +564 -39
  26. package/Runtime/Tags/EffectStackKey.cs +79 -0
  27. package/Runtime/Tags/EffectStackKey.cs.meta +4 -0
  28. package/Runtime/Tags/PeriodicEffectDefinition.cs +102 -0
  29. package/Runtime/Tags/PeriodicEffectDefinition.cs.meta +4 -0
  30. package/Runtime/Tags/PeriodicEffectRuntimeState.cs +40 -0
  31. package/Runtime/Tags/PeriodicEffectRuntimeState.cs.meta +4 -0
  32. package/Runtime/Tags/TagHandler.cs +375 -21
  33. package/Samples~/DI - Zenject/README.md +0 -2
  34. package/Tests/Editor/Attributes/WShowIfPropertyDrawerTests.cs +285 -0
  35. package/Tests/Editor/Attributes/WShowIfPropertyDrawerTests.cs.meta +11 -0
  36. package/Tests/Editor/Core/Attributes/RelationalComponentAssignerTests.cs +2 -2
  37. package/Tests/Editor/Utils/ScriptableObjectSingletonTests.cs +41 -0
  38. package/Tests/Runtime/Serialization/JsonSerializationTest.cs +4 -3
  39. package/Tests/Runtime/Tags/AttributeEffectTests.cs +135 -0
  40. package/Tests/Runtime/Tags/AttributeEffectTests.cs.meta +3 -0
  41. package/Tests/Runtime/Tags/AttributeModificationTests.cs +137 -0
  42. package/Tests/Runtime/Tags/AttributeTests.cs +192 -0
  43. package/Tests/Runtime/Tags/AttributeTests.cs.meta +3 -0
  44. package/Tests/Runtime/Tags/AttributeUtilitiesTests.cs +245 -0
  45. package/Tests/Runtime/Tags/CosmeticAndCollisionTests.cs +1 -1
  46. package/Tests/Runtime/Tags/EffectBehaviorTests.cs +184 -0
  47. package/Tests/Runtime/Tags/EffectBehaviorTests.cs.meta +3 -0
  48. package/Tests/Runtime/Tags/EffectHandlerTests.cs +809 -0
  49. package/Tests/Runtime/Tags/Helpers/RecordingEffectBehavior.cs +89 -0
  50. package/Tests/Runtime/Tags/Helpers/RecordingEffectBehavior.cs.meta +4 -0
  51. package/Tests/Runtime/Tags/PeriodicEffectDefinitionSerializationTests.cs +92 -0
  52. package/Tests/Runtime/Tags/PeriodicEffectDefinitionSerializationTests.cs.meta +3 -0
  53. package/Tests/Runtime/Tags/TagHandlerTests.cs +130 -6
  54. package/package.json +1 -1
  55. package/scripts/lint-doc-links.ps1 +156 -11
  56. package/Tests/Runtime/Tags/AttributeDataTests.cs +0 -312
  57. package/node_modules.meta +0 -8
  58. /package/Tests/Runtime/Tags/{AttributeDataTests.cs.meta → AttributeModificationTests.cs.meta} +0 -0
@@ -0,0 +1,171 @@
1
+ namespace WallstopStudios.UnityHelpers.Tags
2
+ {
3
+ using UnityEngine;
4
+
5
+ /// <summary>
6
+ /// Base class for authoring custom effect behaviours that respond to the lifecycle of an active <see cref="AttributeEffect"/>.
7
+ /// </summary>
8
+ /// <remarks>
9
+ /// <para>
10
+ /// Each behaviour asset is cloned per <see cref="EffectHandle"/>, which means derived classes can safely store mutable state
11
+ /// between calls to <see cref="OnApply(EffectBehaviorContext)"/>, <see cref="OnTick(EffectBehaviorContext)"/>,
12
+ /// <see cref="OnPeriodicTick(EffectBehaviorContext, PeriodicEffectTickContext)"/>, and <see cref="OnRemove(EffectBehaviorContext)"/>.
13
+ /// </para>
14
+ /// <para>
15
+ /// Attach behaviour assets to <see cref="AttributeEffect.behaviors"/> to augment the data-driven attribute pipeline with bespoke
16
+ /// gameplay logic, visual or audio feedback, or integration hooks into other game systems.
17
+ /// </para>
18
+ /// <para>
19
+ /// All callbacks are synchronously invoked by <see cref="EffectHandler"/> on the main thread, ensuring safe interaction with Unity APIs.
20
+ /// </para>
21
+ /// </remarks>
22
+ /// <example>
23
+ /// <code language="csharp">
24
+ /// using UnityEngine;
25
+ /// using WallstopStudios.UnityHelpers.Tags;
26
+ ///
27
+ /// [CreateAssetMenu(menuName = "Game/Effects/Burning Behaviour")]
28
+ /// public sealed class BurningBehavior : EffectBehavior
29
+ /// {
30
+ /// [SerializeField]
31
+ /// private GameObject flamePrefab;
32
+ ///
33
+ /// private GameObject spawnedInstance;
34
+ ///
35
+ /// public override void OnApply(EffectBehaviorContext context)
36
+ /// {
37
+ /// if (flamePrefab == null)
38
+ /// {
39
+ /// return;
40
+ /// }
41
+ ///
42
+ /// Transform parent = context.Target.transform;
43
+ /// spawnedInstance = Object.Instantiate(flamePrefab, parent.position, parent.rotation, parent);
44
+ /// }
45
+ ///
46
+ /// public override void OnPeriodicTick(EffectBehaviorContext context, PeriodicEffectTickContext tickContext)
47
+ /// {
48
+ /// // Cancel the effect early once the periodic bundle has executed three times.
49
+ /// if (tickContext.executedTicks >= 3)
50
+ /// {
51
+ /// context.handler.RemoveEffect(context.handle);
52
+ /// }
53
+ /// }
54
+ ///
55
+ /// public override void OnRemove(EffectBehaviorContext context)
56
+ /// {
57
+ /// if (spawnedInstance != null)
58
+ /// {
59
+ /// Object.Destroy(spawnedInstance);
60
+ /// spawnedInstance = null;
61
+ /// }
62
+ /// }
63
+ /// }
64
+ ///
65
+ /// // Assign the behaviour asset to an AttributeEffect so it is cloned per application.
66
+ /// AttributeEffect burnEffect = ScriptableObject.CreateInstance&lt;AttributeEffect&gt;();
67
+ /// burnEffect.behaviors.Add(burningBehaviorAsset);
68
+ /// </code>
69
+ /// </example>
70
+ public abstract class EffectBehavior : ScriptableObject
71
+ {
72
+ /// <summary>
73
+ /// Invoked once when the effect handle becomes active.
74
+ /// </summary>
75
+ /// <param name="context">Runtime context for the effect instance.</param>
76
+ public virtual void OnApply(EffectBehaviorContext context) { }
77
+
78
+ /// <summary>
79
+ /// Invoked every frame while the effect remains active.
80
+ /// </summary>
81
+ /// <param name="context">Runtime context for the effect instance.</param>
82
+ public virtual void OnTick(EffectBehaviorContext context) { }
83
+
84
+ /// <summary>
85
+ /// Invoked after a periodic tick has been processed for the owning effect.
86
+ /// </summary>
87
+ /// <param name="context">Runtime context for the effect instance.</param>
88
+ /// <param name="tickContext">Information about the specific periodic tick.</param>
89
+ public virtual void OnPeriodicTick(
90
+ EffectBehaviorContext context,
91
+ PeriodicEffectTickContext tickContext
92
+ ) { }
93
+
94
+ /// <summary>
95
+ /// Invoked when the effect handle is removed or expires.
96
+ /// </summary>
97
+ /// <param name="context">Runtime context for the effect instance.</param>
98
+ public virtual void OnRemove(EffectBehaviorContext context) { }
99
+ }
100
+
101
+ /// <summary>
102
+ /// Immutable runtime data passed to behaviour callbacks.
103
+ /// </summary>
104
+ public readonly struct EffectBehaviorContext
105
+ {
106
+ /// <summary>
107
+ /// Gets the effect asset backing the handle.
108
+ /// </summary>
109
+ public AttributeEffect Effect => handle.effect;
110
+
111
+ /// <summary>
112
+ /// Gets the GameObject targeted by the effect handler.
113
+ /// </summary>
114
+ public GameObject Target => handler.gameObject;
115
+
116
+ /// <summary>
117
+ /// Gets the deltaTime used for the current invocation. For <see cref="EffectBehavior.OnApply"/>,
118
+ /// this value is zero.
119
+ /// </summary>
120
+ public readonly float deltaTime;
121
+
122
+ /// <summary>
123
+ /// Gets the handler managing the effect.
124
+ /// </summary>
125
+ public readonly EffectHandler handler;
126
+
127
+ /// <summary>
128
+ /// Gets the handle associated with this behaviour invocation.
129
+ /// </summary>
130
+ public readonly EffectHandle handle;
131
+
132
+ public EffectBehaviorContext(EffectHandler handler, EffectHandle handle, float deltaTime)
133
+ {
134
+ this.handler = handler;
135
+ this.handle = handle;
136
+ this.deltaTime = deltaTime;
137
+ }
138
+ }
139
+
140
+ /// <summary>
141
+ /// Details about a specific periodic tick that just executed.
142
+ /// </summary>
143
+ public readonly struct PeriodicEffectTickContext
144
+ {
145
+ /// <summary>
146
+ /// Gets the periodic definition that produced this tick.
147
+ /// </summary>
148
+ public readonly PeriodicEffectDefinition definition;
149
+
150
+ /// <summary>
151
+ /// Gets the number of ticks executed so far, including this one.
152
+ /// </summary>
153
+ public readonly int executedTicks;
154
+
155
+ /// <summary>
156
+ /// Gets the timestamp when the tick occurred.
157
+ /// </summary>
158
+ public readonly float currentTime;
159
+
160
+ public PeriodicEffectTickContext(
161
+ PeriodicEffectDefinition definition,
162
+ int executedTicks,
163
+ float currentTime
164
+ )
165
+ {
166
+ this.definition = definition;
167
+ this.executedTicks = executedTicks;
168
+ this.currentTime = currentTime;
169
+ }
170
+ }
171
+ }
@@ -0,0 +1,4 @@
1
+ fileFormatVersion: 2
2
+ guid: c5c02017f2cf40f59c135b9cf2d6fb3a
3
+ timeCreated: 1759598400
4
+
@@ -72,6 +72,11 @@ namespace WallstopStudios.UnityHelpers.Tags
72
72
  return new EffectHandle(Interlocked.Increment(ref Id), effect);
73
73
  }
74
74
 
75
+ internal static EffectHandle CreateInstanceInternal()
76
+ {
77
+ return new EffectHandle(Interlocked.Increment(ref Id), null);
78
+ }
79
+
75
80
  private EffectHandle(long id, AttributeEffect effect)
76
81
  {
77
82
  this.id = id;