com.wallstop-studios.unity-helpers 2.0.0-rc81.9 → 2.0.1
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.
- package/.editorconfig +1 -1
- package/.gitattributes +1 -1
- package/.githooks/pre-commit +31 -5
- package/.githooks/pre-push +50 -0
- package/.github/dependabot.yml +24 -2
- package/.github/scripts/check-markdown-links.ps1 +77 -0
- package/.github/scripts/check_markdown_links.py +89 -0
- package/.github/scripts/check_markdown_url_encoding.py +74 -0
- package/.github/scripts/validate_markdown_links.py +194 -0
- package/.github/workflows/csharpier-autofix.yml +152 -0
- package/.github/workflows/format-on-demand.yml +305 -0
- package/.github/workflows/lint-doc-links.yml +8 -5
- package/.github/workflows/markdown-json.yml +6 -2
- package/.github/workflows/npm-publish.yml +1 -1
- package/.github/workflows/prettier-autofix.yml +195 -0
- package/.github/workflows/update-dotnet-tools.yml +80 -0
- package/.github/workflows/yaml-format-lint.yml +41 -0
- package/.lychee.toml +4 -4
- package/.markdownlint.jsonc +21 -0
- package/.pre-commit-config.yaml +11 -3
- package/.yamllint.yaml +31 -0
- package/AGENTS.md +5 -1
- package/Docs/CHANGELOG.md +11 -0
- package/Docs/CONTRIBUTING.md +49 -0
- package/Docs/CONTRIBUTING.md.meta +7 -0
- package/{EDITOR_TOOLS_GUIDE.md → Docs/EDITOR_TOOLS_GUIDE.md} +4 -0
- package/Docs/EFFECTS_SYSTEM.md +1316 -0
- package/{EFFECTS_SYSTEM_TUTORIAL.md → Docs/EFFECTS_SYSTEM_TUTORIAL.md} +1 -1
- package/{GETTING_STARTED.md → Docs/GETTING_STARTED.md} +50 -64
- package/{GLOSSARY.md → Docs/GLOSSARY.md} +4 -4
- package/Docs/HELPER_UTILITIES.md +885 -0
- package/Docs/HELPER_UTILITIES.md.meta +7 -0
- package/{INDEX.md → Docs/INDEX.md} +107 -62
- package/Docs/MATH_AND_EXTENSIONS.md +1039 -0
- package/{RANDOM_PERFORMANCE.md → Docs/RANDOM_PERFORMANCE.md} +15 -15
- package/{RELATIONAL_COMPONENTS.md → Docs/RELATIONAL_COMPONENTS.md} +111 -84
- package/{SERIALIZATION.md → Docs/SERIALIZATION.md} +15 -0
- package/{SPATIAL_TREES_2D_GUIDE.md → Docs/SPATIAL_TREES_2D_GUIDE.md} +2 -2
- package/{SPATIAL_TREES_3D_GUIDE.md → Docs/SPATIAL_TREES_3D_GUIDE.md} +1 -1
- package/Docs/SPATIAL_TREE_2D_PERFORMANCE.md +241 -0
- package/Docs/SPATIAL_TREE_3D_PERFORMANCE.md +243 -0
- package/{THIRD_PARTY_NOTICES.md → Docs/THIRD_PARTY_NOTICES.md} +1 -1
- package/Docs/UTILITY_COMPONENTS.md +906 -0
- package/Docs/UTILITY_COMPONENTS.md.meta +7 -0
- package/Docs/VISUAL_COMPONENTS.md +337 -0
- package/Docs/VISUAL_COMPONENTS.md.meta +7 -0
- package/Editor/AnimationEventEditor.cs +337 -160
- package/Editor/Core/Helper/AnimationEventHelpers.cs +178 -152
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs +20 -11
- package/Editor/CustomEditors/TexturePlatformOverrideEntryDrawer.cs +11 -2
- package/Editor/FitTextureSizeWindow.cs +43 -19
- package/Editor/PersistentDirectorySettings.cs +64 -12
- package/Editor/PrefabChecker.cs +72 -5
- package/Editor/Sprites/AnimationCopier.cs +131 -55
- package/Editor/Sprites/AnimationCreator.cs +63 -22
- package/Editor/Sprites/AnimationViewerWindow.cs +42 -6
- package/Editor/Sprites/TexturePlatformNameHelper.cs +50 -39
- package/Editor/Sprites/TextureResizerWizard.cs +23 -1
- package/Editor/Sprites/TextureSettingsApplierWindow.cs +148 -85
- package/Editor/Tools/ImageBlurTool.cs +81 -10
- package/Editor/Utils/EditorUi.cs +1 -1
- package/Editor/Utils/ScriptableObjectSingletonCreator.cs +1 -1
- package/README.md +428 -2433
- package/Runtime/AssemblyInfo.cs +4 -0
- package/Runtime/Core/Attributes/NotNullAttribute.cs +1 -3
- package/Runtime/Core/Attributes/RelationalComponentAssigner.cs +50 -5
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +0 -1
- package/Runtime/Core/DataStructure/KDTree3D.cs +1 -1
- package/Runtime/Core/DataStructure/OctTree3D.cs +1 -1
- package/Runtime/Core/Extension/AsyncOperationExtensions.cs +122 -0
- package/Runtime/Core/Extension/RandomExtensions.cs +68 -0
- package/Runtime/Core/Extension/WallstopStudiosLogger.cs +16 -0
- package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +4 -1
- package/Runtime/Core/Helper/ReflectionHelpers.cs +21 -10
- package/Runtime/Core/Helper/SpriteHelpers.cs +3 -1
- package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs +45 -1
- package/Runtime/Core/Serialization/JsonConverters/GameObjectConverter.cs +13 -5
- package/Runtime/Core/Serialization/JsonConverters/ResolutionConverter.cs +1 -1
- package/Runtime/Core/Serialization/JsonConverters/TypeConverter.cs +1 -1
- package/Runtime/Core/Serialization/ProtobufUnitySurrogates.cs +24 -29
- package/Runtime/Core/Serialization/Serializer.cs +101 -0
- package/Runtime/Integrations/Reflex/AssemblyInfo.cs +7 -0
- package/Runtime/Integrations/Reflex/AssemblyInfo.cs.meta +11 -0
- package/Runtime/Integrations/Reflex/ContainerRelationalExtensions.cs +198 -0
- package/Runtime/Integrations/Reflex/ContainerRelationalExtensions.cs.meta +11 -0
- package/Runtime/Integrations/Reflex/RelationalComponentsInstaller.cs +86 -0
- package/Runtime/Integrations/Reflex/RelationalComponentsInstaller.cs.meta +11 -0
- package/Runtime/Integrations/Reflex/RelationalReflexSceneBootstrapper.cs +316 -0
- package/Runtime/Integrations/Reflex/RelationalReflexSceneBootstrapper.cs.meta +11 -0
- package/Runtime/Integrations/Reflex/RelationalSceneAssignmentOptions.cs +86 -0
- package/Runtime/Integrations/Reflex/RelationalSceneAssignmentOptions.cs.meta +11 -0
- package/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Integration.Reflex.asmdef +20 -0
- package/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Integration.Reflex.asmdef.meta +7 -0
- package/Runtime/Integrations/Reflex.meta +8 -0
- package/Runtime/Integrations/VContainer/AssemblyInfo.cs +9 -0
- package/Runtime/Integrations/VContainer/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Integrations/VContainer/ObjectResolverRelationalExtensions.cs +96 -0
- package/Runtime/Integrations/VContainer/RelationalComponentEntryPoint.cs +90 -10
- package/Runtime/Integrations/VContainer/RelationalComponentsBuilderExtensions.cs +13 -1
- package/Runtime/Integrations/VContainer/RelationalObjectPools.cs +114 -0
- package/Runtime/Integrations/VContainer/RelationalObjectPools.cs.meta +11 -0
- package/Runtime/Integrations/VContainer/RelationalSceneAssignmentOptions.cs +16 -4
- package/Runtime/Integrations/VContainer/RelationalSceneLoadListener.cs +241 -0
- package/Runtime/Integrations/VContainer/RelationalSceneLoadListener.cs.meta +11 -0
- package/Runtime/Integrations/Zenject/AssemblyInfo.cs +9 -0
- package/Runtime/Integrations/Zenject/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Integrations/Zenject/DiContainerRelationalExtensions.cs +69 -2
- package/Runtime/Integrations/Zenject/RelationalComponentSceneInitializer.cs +89 -12
- package/Runtime/Integrations/Zenject/RelationalComponentsInstaller.cs +23 -1
- package/Runtime/Integrations/Zenject/RelationalMemoryPools.cs +44 -0
- package/Runtime/Integrations/Zenject/RelationalMemoryPools.cs.meta +11 -0
- package/Runtime/Integrations/Zenject/RelationalSceneAssignmentOptions.cs +16 -10
- package/Runtime/Integrations/Zenject/RelationalSceneLoadListener.cs +243 -0
- package/Runtime/Integrations/Zenject/RelationalSceneLoadListener.cs.meta +11 -0
- package/Runtime/Tags/AttributeMetadataCache.cs +1 -4
- package/Runtime/Utils/Buffers.cs +4 -4
- package/Runtime/Utils/ScriptableObjectSingleton.cs +1 -2
- package/Runtime/Utils/SetTextureImportData.cs +3 -1
- package/Runtime/Utils/TextureScale.cs +10 -2
- package/Runtime/Visuals/UGUI/EnhancedImage.cs +6 -0
- package/Runtime/Visuals/UIToolkit/LayeredImage.cs +4 -1
- package/Samples~/DI - Reflex/README.md +527 -0
- package/Samples~/DI - Reflex/README.md.meta +7 -0
- package/Samples~/DI - Reflex/Scripts/ReflexPaletteService.cs +36 -0
- package/Samples~/DI - Reflex/Scripts/ReflexPaletteService.cs.meta +11 -0
- package/Samples~/DI - Reflex/Scripts/ReflexRelationalConsumer.cs +79 -0
- package/Samples~/DI - Reflex/Scripts/ReflexRelationalConsumer.cs.meta +11 -0
- package/Samples~/DI - Reflex/Scripts/ReflexSampleInstaller.cs +30 -0
- package/Samples~/DI - Reflex/Scripts/ReflexSampleInstaller.cs.meta +11 -0
- package/Samples~/DI - Reflex/Scripts/ReflexSpawner.cs +79 -0
- package/Samples~/DI - Reflex/Scripts/ReflexSpawner.cs.meta +11 -0
- package/Samples~/DI - Reflex/Scripts/Samples.UnityHelpers.DI.Reflex.asmdef +26 -0
- package/Samples~/DI - Reflex/Scripts/Samples.UnityHelpers.DI.Reflex.asmdef.meta +9 -0
- package/Samples~/DI - Reflex/Scripts.meta +8 -0
- package/Samples~/DI - Reflex.meta +8 -0
- package/Samples~/DI - VContainer/README.md +238 -56
- package/Samples~/DI - VContainer/Scripts/GameLifetimeScope.cs +22 -4
- package/Samples~/DI - VContainer/Scripts/RelationalConsumer.cs +5 -2
- package/Samples~/DI - VContainer/Scripts/Spawner.cs +113 -4
- package/Samples~/DI - Zenject/README.md +223 -58
- package/Samples~/DI - Zenject/Scripts/RelationalConsumer.cs +3 -0
- package/Samples~/DI - Zenject/Scripts/RelationalConsumerPool.cs +37 -0
- package/Samples~/DI - Zenject/Scripts/RelationalConsumerPool.cs.meta +12 -0
- package/Samples~/DI - Zenject/Scripts/SpawnerZenject.cs +74 -3
- package/Samples~/Random - PRNG/README.md +2 -1
- package/Samples~/Relational Components - Basic/README.md +3 -1
- package/Samples~/Serialization - JSON/README.md +2 -1
- package/Samples~/Spatial Structures - 2D and 3D/README.md +2 -1
- package/Samples~/UGUI - EnhancedImage/README.md +2 -1
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/README.md +2 -1
- package/Tests/Editor/Attributes/AnimationEventHelpersTests.cs +16 -0
- package/Tests/Editor/Core/Attributes/RelationalComponentAssignerTests.cs +32 -34
- package/Tests/Editor/Integrations/Reflex/ReflexIntegrationCompilationTests.cs +41 -0
- package/Tests/Editor/Integrations/Reflex/ReflexIntegrationCompilationTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Editor.Reflex.asmdef +27 -0
- package/Tests/Editor/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Editor.Reflex.asmdef.meta +7 -0
- package/Tests/Editor/Integrations/Reflex.meta +8 -0
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalEntryPointTests.cs +21 -18
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalHelpersTests.cs +164 -0
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalHelpersTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/VContainer/WallstopStudios.UnityHelpers.Tests.Editor.VContainer.asmdef +2 -1
- package/Tests/Editor/Integrations/Zenject/WallstopStudios.UnityHelpers.Tests.Editor.Zenject.asmdef +3 -2
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalHelpersTests.cs +127 -0
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalHelpersTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalInitializerTests.cs +25 -23
- package/Tests/Editor/PersistentDirectorySettingsTests.cs +58 -0
- package/Tests/Editor/PersistentDirectorySettingsTests.cs.meta +11 -0
- package/Tests/Editor/PrefabCheckerReportTests.cs +32 -0
- package/Tests/Editor/PrefabCheckerReportTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs +63 -0
- package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/AnimationCopierWindowTests.cs +1 -1
- package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs +38 -0
- package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/ScriptableSpriteAtlasEditorTests.cs +1 -1
- package/Tests/Editor/Sprites/SpriteCropperAdditionalTests.cs +12 -12
- package/Tests/Editor/Sprites/SpriteCropperTests.cs +9 -9
- package/Tests/Editor/Sprites/SpritePivotAdjusterTests.cs +3 -3
- package/Tests/Editor/Sprites/TexturePlatformNameHelperTests.cs +18 -0
- package/Tests/Editor/Sprites/TextureResizerWizardTests.cs +5 -5
- package/Tests/Editor/Sprites/TextureSettingsApplierAPITests.cs +3 -3
- package/Tests/Editor/Sprites/TextureSettingsApplierWizardAdditionalTests.cs +4 -4
- package/Tests/Editor/Sprites/TextureSettingsApplierWizardTests.cs +4 -4
- package/Tests/Editor/Tools/ImageBlurToolTests.cs +22 -110
- package/Tests/Editor/Utils/CommonTestBase.cs +60 -1
- package/Tests/Editor/Utils/ScriptableObjectSingletonCreatorTests.cs +6 -6
- package/Tests/Editor/Windows/FitTextureSizeWindowTests.cs +66 -74
- package/Tests/Runtime/Attributes/RelationalComponentInitializerTests.cs +4 -15
- package/Tests/Runtime/DataStructures/SpatialTree3DBoundsConsistencyTests.cs +29 -29
- package/Tests/Runtime/Extensions/AsyncOperationExtensionsTests.cs +179 -0
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs +55 -0
- package/Tests/Runtime/Integrations/Reflex/RelationalComponentsReflexTests.cs +445 -0
- package/Tests/Runtime/Integrations/Reflex/RelationalComponentsReflexTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Runtime.Reflex.asmdef +28 -0
- package/Tests/Runtime/Integrations/Reflex/WallstopStudios.UnityHelpers.Tests.Runtime.Reflex.asmdef.meta +7 -0
- package/Tests/Runtime/Integrations/Reflex.meta +8 -0
- package/Tests/Runtime/Integrations/VContainer/RelationalComponentsVContainerTests.cs +257 -221
- package/Tests/Runtime/Integrations/VContainer/RelationalObjectPoolsVContainerTests.cs +91 -0
- package/Tests/Runtime/Integrations/VContainer/RelationalObjectPoolsVContainerTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/Zenject/RelationalComponentsZenjectTests.cs +251 -233
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs +1 -1
- package/Tests/Runtime/Performance/SpatialTree2DPerformanceTests.cs +6 -1
- package/Tests/Runtime/Performance/SpatialTree3DPerformanceTests.cs +4 -1
- package/Tests/Runtime/Serialization/JsonConverterAdditionalTests.cs +30 -0
- package/Tests/Runtime/Serialization/JsonConverterAdditionalTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/JsonConverterTests.cs +8 -12
- package/Tests/Runtime/Serialization/JsonRoundtripComprehensiveTests.cs +4 -9
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs +16 -5
- package/Tests/Runtime/Serialization/ProtoRoundtripComprehensiveTests.cs +13 -13
- package/Tests/Runtime/Serialization/SerializerAdditionalTests.cs +12 -0
- package/Tests/Runtime/Serialization/SerializerFileIoTests.cs +105 -0
- package/Tests/Runtime/Serialization/SerializerFileIoTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/UnityEngineObjectJsonTests.cs +247 -0
- package/Tests/Runtime/Serialization/UnityEngineObjectJsonTests.cs.meta +11 -0
- package/Tests/Runtime/TestUtils/CommonTestBase.cs +99 -0
- package/Tests/Runtime/TestUtils/ReflexTestSupport.cs +111 -0
- package/Tests/Runtime/TestUtils/ReflexTestSupport.cs.meta +12 -0
- package/Tests/Runtime/Utils/CoroutineHandlerTests.cs +1 -1
- package/Tests/Runtime/Utils/LZMAComprehensiveTests.cs +1 -1
- package/Tests/Runtime/Utils/LZMATests.cs +1 -1
- package/Tests/Runtime/Utils/MatchColliderToSpriteTests.cs +5 -5
- package/Tests/Runtime/Visuals/EnhancedImageTests.cs +25 -56
- package/Tests/Runtime/Visuals/VisualsTestHelpers.cs +1 -8
- package/Tests/TestUtils.meta +8 -0
- package/package-lock.json.meta +7 -0
- package/package.json +13 -4
- package/scripts/check-eol.ps1 +4 -5
- package/scripts/lint-tests.ps1 +156 -0
- package/scripts/lint-tests.ps1.meta +7 -0
- package/scripts/normalize-eol.ps1 +6 -9
- package/.github/workflows/csharpier.yml +0 -135
- package/CHANGELOG.md +0 -0
- package/EFFECTS_SYSTEM.md +0 -242
- package/MATH_AND_EXTENSIONS.md +0 -316
- package/SPATIAL_TREE_2D_PERFORMANCE.md +0 -238
- package/SPATIAL_TREE_3D_PERFORMANCE.md +0 -240
- /package/{CHANGELOG.md.meta → Docs/CHANGELOG.md.meta} +0 -0
- /package/{DATA_STRUCTURES.md → Docs/DATA_STRUCTURES.md} +0 -0
- /package/{DATA_STRUCTURES.md.meta → Docs/DATA_STRUCTURES.md.meta} +0 -0
- /package/{EDITOR_TOOLS_GUIDE.md.meta → Docs/EDITOR_TOOLS_GUIDE.md.meta} +0 -0
- /package/{EFFECTS_SYSTEM.md.meta → Docs/EFFECTS_SYSTEM.md.meta} +0 -0
- /package/{EFFECTS_SYSTEM_TUTORIAL.md.meta → Docs/EFFECTS_SYSTEM_TUTORIAL.md.meta} +0 -0
- /package/{GETTING_STARTED.md.meta → Docs/GETTING_STARTED.md.meta} +0 -0
- /package/{GLOSSARY.md.meta → Docs/GLOSSARY.md.meta} +0 -0
- /package/{HULLS.md → Docs/HULLS.md} +0 -0
- /package/{HULLS.md.meta → Docs/HULLS.md.meta} +0 -0
- /package/{INDEX.md.meta → Docs/INDEX.md.meta} +0 -0
- /package/{LICENSE.md → Docs/LICENSE.md} +0 -0
- /package/{LICENSE.md.meta → Docs/LICENSE.md.meta} +0 -0
- /package/{MATH_AND_EXTENSIONS.md.meta → Docs/MATH_AND_EXTENSIONS.md.meta} +0 -0
- /package/{RANDOM_PERFORMANCE.md.meta → Docs/RANDOM_PERFORMANCE.md.meta} +0 -0
- /package/{REFLECTION_HELPERS.md → Docs/REFLECTION_HELPERS.md} +0 -0
- /package/{REFLECTION_HELPERS.md.meta → Docs/REFLECTION_HELPERS.md.meta} +0 -0
- /package/{RELATIONAL_COMPONENTS.md.meta → Docs/RELATIONAL_COMPONENTS.md.meta} +0 -0
- /package/{SERIALIZATION.md.meta → Docs/SERIALIZATION.md.meta} +0 -0
- /package/{SINGLETONS.md → Docs/SINGLETONS.md} +0 -0
- /package/{SINGLETONS.md.meta → Docs/SINGLETONS.md.meta} +0 -0
- /package/{SPATIAL_TREES_2D_GUIDE.md.meta → Docs/SPATIAL_TREES_2D_GUIDE.md.meta} +0 -0
- /package/{SPATIAL_TREES_3D_GUIDE.md.meta → Docs/SPATIAL_TREES_3D_GUIDE.md.meta} +0 -0
- /package/{SPATIAL_TREE_2D_PERFORMANCE.md.meta → Docs/SPATIAL_TREE_2D_PERFORMANCE.md.meta} +0 -0
- /package/{SPATIAL_TREE_3D_PERFORMANCE.md.meta → Docs/SPATIAL_TREE_3D_PERFORMANCE.md.meta} +0 -0
- /package/{SPATIAL_TREE_SEMANTICS.md → Docs/SPATIAL_TREE_SEMANTICS.md} +0 -0
- /package/{SPATIAL_TREE_SEMANTICS.md.meta → Docs/SPATIAL_TREE_SEMANTICS.md.meta} +0 -0
- /package/{THIRD_PARTY_NOTICES.md.meta → Docs/THIRD_PARTY_NOTICES.md.meta} +0 -0
package/Runtime/Utils/Buffers.cs
CHANGED
|
@@ -1113,21 +1113,21 @@ namespace WallstopStudios.UnityHelpers.Utils
|
|
|
1113
1113
|
/// This struct implements IDisposable to enable automatic resource return via 'using' statements.
|
|
1114
1114
|
/// The resource is returned to its pool when Dispose is called, typically at the end of a 'using' block.
|
|
1115
1115
|
/// </remarks>
|
|
1116
|
-
public
|
|
1116
|
+
public struct PooledResource<T> : IDisposable
|
|
1117
1117
|
{
|
|
1118
1118
|
/// <summary>
|
|
1119
1119
|
/// The pooled resource instance. Access this to use the resource.
|
|
1120
1120
|
/// </summary>
|
|
1121
1121
|
public readonly T resource;
|
|
1122
1122
|
private readonly Action<T> _onDispose;
|
|
1123
|
-
private
|
|
1123
|
+
private bool _initialized;
|
|
1124
1124
|
|
|
1125
1125
|
/// <summary>
|
|
1126
1126
|
/// Creates a new PooledResource wrapping the specified resource with a disposal action.
|
|
1127
1127
|
/// </summary>
|
|
1128
1128
|
/// <param name="resource">The resource to wrap.</param>
|
|
1129
1129
|
/// <param name="onDispose">The action to invoke when disposing, typically returning the resource to a pool.</param>
|
|
1130
|
-
|
|
1130
|
+
public PooledResource(T resource, Action<T> onDispose)
|
|
1131
1131
|
{
|
|
1132
1132
|
_initialized = true;
|
|
1133
1133
|
this.resource = resource;
|
|
@@ -1144,7 +1144,7 @@ namespace WallstopStudios.UnityHelpers.Utils
|
|
|
1144
1144
|
{
|
|
1145
1145
|
return;
|
|
1146
1146
|
}
|
|
1147
|
-
|
|
1147
|
+
_initialized = false;
|
|
1148
1148
|
_onDispose(resource);
|
|
1149
1149
|
}
|
|
1150
1150
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
namespace WallstopStudios.UnityHelpers.Utils
|
|
2
2
|
{
|
|
3
3
|
using System;
|
|
4
|
-
using System.Linq;
|
|
5
4
|
using UnityEngine;
|
|
6
5
|
using WallstopStudios.UnityHelpers.Core.Attributes;
|
|
7
6
|
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
@@ -25,7 +24,7 @@ namespace WallstopStudios.UnityHelpers.Utils
|
|
|
25
24
|
///
|
|
26
25
|
/// If multiple assets are found, a warning is logged and the first result ordered by name is returned.
|
|
27
26
|
/// The editor utility “ScriptableObject Singleton Creator” automatically creates and relocates assets to
|
|
28
|
-
/// the correct path on editor load — see EDITOR_TOOLS_GUIDE.md#scriptableobject-singleton-creator.
|
|
27
|
+
/// the correct path on editor load — see Docs/EDITOR_TOOLS_GUIDE.md#scriptableobject-singleton-creator.
|
|
29
28
|
///
|
|
30
29
|
/// ODIN compatibility: When the <c>ODIN_INSPECTOR</c> symbol is defined, this class derives from
|
|
31
30
|
/// <c>Sirenix.OdinInspector.SerializedScriptableObject</c>; otherwise it derives from <see cref="ScriptableObject"/>.
|
|
@@ -36,10 +36,14 @@ namespace WallstopStudios.UnityHelpers.Utils
|
|
|
36
36
|
/// This method modifies the texture in-place. Point sampling provides fast, sharp scaling
|
|
37
37
|
/// but may produce pixelated results. Use Bilinear for smoother results.
|
|
38
38
|
/// </remarks>
|
|
39
|
-
public static void Point(Texture2D tex, int newWidth, int newHeight)
|
|
39
|
+
public static void Point(Texture2D tex, int newWidth, int newHeight, bool apply = false)
|
|
40
40
|
{
|
|
41
41
|
ValidateInputs(tex, newWidth, newHeight);
|
|
42
42
|
ThreadedScale(tex, newWidth, newHeight, false);
|
|
43
|
+
if (apply)
|
|
44
|
+
{
|
|
45
|
+
tex.Apply(updateMipmaps: false, makeNoLongerReadable: false);
|
|
46
|
+
}
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
/// <summary>
|
|
@@ -55,10 +59,14 @@ namespace WallstopStudios.UnityHelpers.Utils
|
|
|
55
59
|
/// This method modifies the texture in-place. Bilinear interpolation provides smooth scaling
|
|
56
60
|
/// with better visual quality than point sampling, at a slight performance cost.
|
|
57
61
|
/// </remarks>
|
|
58
|
-
public static void Bilinear(Texture2D tex, int newWidth, int newHeight)
|
|
62
|
+
public static void Bilinear(Texture2D tex, int newWidth, int newHeight, bool apply = false)
|
|
59
63
|
{
|
|
60
64
|
ValidateInputs(tex, newWidth, newHeight);
|
|
61
65
|
ThreadedScale(tex, newWidth, newHeight, true);
|
|
66
|
+
if (apply)
|
|
67
|
+
{
|
|
68
|
+
tex.Apply(updateMipmaps: false, makeNoLongerReadable: false);
|
|
69
|
+
}
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
private static void ValidateInputs(Texture2D tex, int newWidth, int newHeight)
|
|
@@ -70,6 +70,7 @@ namespace WallstopStudios.UnityHelpers.Visuals.UGUI
|
|
|
70
70
|
/// Stores the dedicated material instance produced by <see cref="UpdateMaterialInstance"/>.
|
|
71
71
|
/// </summary>
|
|
72
72
|
private Material _cachedMaterialInstance;
|
|
73
|
+
internal Material CachedMaterialInstanceForTests => _cachedMaterialInstance;
|
|
73
74
|
|
|
74
75
|
/// <summary>
|
|
75
76
|
/// HDR-capable tint applied to the instantiated material. Values above 1 keep their intensity instead of being clamped.
|
|
@@ -214,5 +215,10 @@ namespace WallstopStudios.UnityHelpers.Visuals.UGUI
|
|
|
214
215
|
_cachedMaterialInstance = null;
|
|
215
216
|
}
|
|
216
217
|
}
|
|
218
|
+
|
|
219
|
+
// Test helpers to avoid reflection
|
|
220
|
+
internal void InvokeStartForTests() => Start();
|
|
221
|
+
|
|
222
|
+
internal void InvokeOnDestroyForTests() => OnDestroy();
|
|
217
223
|
}
|
|
218
224
|
}
|
|
@@ -6,11 +6,13 @@ namespace WallstopStudios.UnityHelpers.Visuals.UIToolkit
|
|
|
6
6
|
using System.Linq;
|
|
7
7
|
using System.Runtime.CompilerServices;
|
|
8
8
|
using System.Threading.Tasks;
|
|
9
|
-
using UnityEditor;
|
|
10
9
|
using UnityEngine;
|
|
11
10
|
using UnityEngine.UIElements;
|
|
12
11
|
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
13
12
|
using WallstopStudios.UnityHelpers.Utils;
|
|
13
|
+
#if UNITY_EDITOR
|
|
14
|
+
using UnityEditor;
|
|
15
|
+
#endif
|
|
14
16
|
|
|
15
17
|
public sealed class LayeredImage : VisualElement
|
|
16
18
|
{
|
|
@@ -68,6 +70,7 @@ namespace WallstopStudios.UnityHelpers.Visuals.UIToolkit
|
|
|
68
70
|
|
|
69
71
|
private readonly AnimatedSpriteLayer[] _layers;
|
|
70
72
|
private readonly Texture2D[] _computed;
|
|
73
|
+
internal Texture2D[] ComputedTexturesForTests => _computed;
|
|
71
74
|
private readonly Color _backgroundColor;
|
|
72
75
|
private readonly Rect? _largestArea;
|
|
73
76
|
private readonly Stopwatch _timer;
|
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
# Reflex Integration - Unity Helpers
|
|
2
|
+
|
|
3
|
+
## Why This Integration Matters
|
|
4
|
+
|
|
5
|
+
**Stop Writing GetComponent Boilerplate in Every Single Script**
|
|
6
|
+
|
|
7
|
+
When using dependency injection with Reflex, you've solved half the problem - your service dependencies get injected cleanly. But you're **still stuck** writing repetitive `GetComponent` boilerplate for hierarchy references in every. single. MonoBehaviour.
|
|
8
|
+
|
|
9
|
+
**The Painful Reality:**
|
|
10
|
+
|
|
11
|
+
1. **Dependencies** → ✅ Handled by Reflex (IHealthSystem, IAudioService, etc.)
|
|
12
|
+
2. **Hierarchy references** → ❌ Still manual hell (SpriteRenderer, Rigidbody2D, child colliders, etc.)
|
|
13
|
+
|
|
14
|
+
You're using a modern DI framework but still writing 2008-era Unity boilerplate. **Unity Helpers fixes this.**
|
|
15
|
+
|
|
16
|
+
**The Solution:** This integration automatically wires up relational component fields **right after** DI injection completes - giving you the best of both worlds with **literally zero extra code per component**.
|
|
17
|
+
|
|
18
|
+
### ⚡ Quick Example: Before vs After
|
|
19
|
+
|
|
20
|
+
**Before (Manual):**
|
|
21
|
+
|
|
22
|
+
```csharp
|
|
23
|
+
public class Enemy : MonoBehaviour
|
|
24
|
+
{
|
|
25
|
+
[Inject] private IHealthSystem _healthSystem;
|
|
26
|
+
private Animator _animator;
|
|
27
|
+
private Rigidbody2D _rigidbody;
|
|
28
|
+
private Collider2D[] _childColliders;
|
|
29
|
+
|
|
30
|
+
void Awake()
|
|
31
|
+
{
|
|
32
|
+
_animator = GetComponent<Animator>();
|
|
33
|
+
_rigidbody = GetComponent<Rigidbody2D>();
|
|
34
|
+
_childColliders = GetComponentsInChildren<Collider2D>();
|
|
35
|
+
// 10+ more lines of GetComponent calls...
|
|
36
|
+
|
|
37
|
+
if (_animator == null) Debug.LogError("Missing Animator!");
|
|
38
|
+
if (_rigidbody == null) Debug.LogError("Missing Rigidbody2D!");
|
|
39
|
+
// More validation...
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**After (With Integration):**
|
|
45
|
+
|
|
46
|
+
```csharp
|
|
47
|
+
public class Enemy : MonoBehaviour
|
|
48
|
+
{
|
|
49
|
+
[Inject] private IHealthSystem _healthSystem;
|
|
50
|
+
|
|
51
|
+
[SiblingComponent] private Animator _animator;
|
|
52
|
+
[SiblingComponent] private Rigidbody2D _rigidbody;
|
|
53
|
+
[ChildComponent] private Collider2D[] _childColliders;
|
|
54
|
+
|
|
55
|
+
// That's it! No Awake() needed - both DI and relational fields are auto-wired
|
|
56
|
+
// Automatic validation with helpful error messages included
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**⏱️ Time Saved:** 10-20 lines of boilerplate per component × hundreds of components = **weeks** of development time.
|
|
61
|
+
**🧠 Mental Load Eliminated:** No more context-switching between DI patterns and Unity hierarchy patterns.
|
|
62
|
+
**🐛 Bugs Prevented:** Automatic validation catches missing references **before** they cause runtime errors.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 🚀 Quick Setup (2 Minutes)
|
|
67
|
+
|
|
68
|
+
### Step 1: Add the Installer to Your SceneScope
|
|
69
|
+
|
|
70
|
+
1. Add a `SceneScope` to your scene (Reflex component)
|
|
71
|
+
2. Add the `RelationalComponentsInstaller` component to the same GameObject
|
|
72
|
+
3. Enable **"Assign Scene On Initialize"** to automatically wire all scene components after the container builds (recommended)
|
|
73
|
+
|
|
74
|
+
> 💡 **Beginner tip:** Enable all checkboxes in the inspector:
|
|
75
|
+
>
|
|
76
|
+
> - ✅ **Assign Scene On Initialize** → Auto-wires all scene objects (saves you from calling it manually)
|
|
77
|
+
> - ✅ **Include Inactive Objects** → Scans disabled GameObjects too
|
|
78
|
+
> - ✅ **Listen For Additive Scenes** → Auto-wires newly loaded scenes (great for multi-scene setups)
|
|
79
|
+
> - ✅ **Use Single Pass Scan** → Faster scanning (always leave this on)
|
|
80
|
+
|
|
81
|
+
### Step 2: Use With Prefab Instantiation
|
|
82
|
+
|
|
83
|
+
When spawning prefabs at runtime, use the helpers that combine instantiation, DI, and relational assignment:
|
|
84
|
+
|
|
85
|
+
```csharp
|
|
86
|
+
using UnityEngine;
|
|
87
|
+
using Reflex.Core;
|
|
88
|
+
using Reflex.Extensions;
|
|
89
|
+
using WallstopStudios.UnityHelpers.Integrations.Reflex;
|
|
90
|
+
|
|
91
|
+
public sealed class EnemySpawner : MonoBehaviour
|
|
92
|
+
{
|
|
93
|
+
[SerializeField] private Enemy _enemyPrefab;
|
|
94
|
+
[SerializeField] private GameObject _enemySquadPrefab;
|
|
95
|
+
|
|
96
|
+
private Container _container;
|
|
97
|
+
|
|
98
|
+
private void Awake()
|
|
99
|
+
{
|
|
100
|
+
_container = gameObject.scene.GetSceneContainer();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
public Enemy SpawnEnemy(Transform parent)
|
|
104
|
+
{
|
|
105
|
+
return _container.InstantiateComponentWithRelations(_enemyPrefab, parent);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public GameObject SpawnEnemySquad(Transform parent)
|
|
109
|
+
{
|
|
110
|
+
return _container.InstantiateGameObjectWithRelations(
|
|
111
|
+
_enemySquadPrefab,
|
|
112
|
+
parent,
|
|
113
|
+
includeInactiveChildren: true
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public void HydrateExisting(GameObject root)
|
|
118
|
+
{
|
|
119
|
+
_container.InjectGameObjectWithRelations(root, includeInactiveChildren: true);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**That's it!** Both DI injection and relational component wiring happen automatically.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 📦 What's Included in This Sample
|
|
129
|
+
|
|
130
|
+
This sample provides a complete working example:
|
|
131
|
+
|
|
132
|
+
- **Scripts/ReflexSampleInstaller.cs** - Registers a palette service to demonstrate DI working alongside relational attributes
|
|
133
|
+
- **Scripts/ReflexRelationalConsumer.cs** - Component demonstrating relational attributes working with Reflex injection
|
|
134
|
+
- **Scripts/ReflexSpawner.cs** - Demonstrates `InstantiateComponentWithRelations`, `InstantiateGameObjectWithRelations`, and hierarchy hydration
|
|
135
|
+
- **Scripts/ReflexPaletteService.cs** - Sample service showing DI pathway is active
|
|
136
|
+
- **Prefabs/** - Example prefabs with relational fields
|
|
137
|
+
- **Scenes/Reflex_Sample.unity** - Complete working scene with SceneScope
|
|
138
|
+
|
|
139
|
+
### How to Import This Sample
|
|
140
|
+
|
|
141
|
+
1. Open Unity Package Manager
|
|
142
|
+
2. Find **Unity Helpers** in the package list
|
|
143
|
+
3. Expand the **Samples** section
|
|
144
|
+
4. Click **Import** next to "DI - Reflex"
|
|
145
|
+
5. Open `Scenes/Reflex_Sample.unity` and press Play
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 🎯 Common Use Cases (By Experience Level)
|
|
150
|
+
|
|
151
|
+
### 🟢 Beginner: "I just want my components to work"
|
|
152
|
+
|
|
153
|
+
**Perfect for:** Player controllers, enemy AI, simple gameplay scripts
|
|
154
|
+
|
|
155
|
+
**What you get:** No more `GetComponent` calls, no more null reference exceptions from missing components
|
|
156
|
+
|
|
157
|
+
**Example:**
|
|
158
|
+
|
|
159
|
+
```csharp
|
|
160
|
+
public class PlayerController : MonoBehaviour
|
|
161
|
+
{
|
|
162
|
+
// Injected dependencies
|
|
163
|
+
[Inject] private IInputService _input;
|
|
164
|
+
[Inject] private IAudioService _audio;
|
|
165
|
+
|
|
166
|
+
// Hierarchy references (auto-wired)
|
|
167
|
+
[SiblingComponent] private Animator _animator;
|
|
168
|
+
[SiblingComponent] private Rigidbody2D _rigidbody;
|
|
169
|
+
[ChildComponent(TagFilter = "Weapon")] private Weapon _weapon;
|
|
170
|
+
|
|
171
|
+
// Everything wired automatically when scene loads!
|
|
172
|
+
|
|
173
|
+
void Update()
|
|
174
|
+
{
|
|
175
|
+
Vector2 input = _input.GetMovementInput();
|
|
176
|
+
_rigidbody.velocity = input * moveSpeed;
|
|
177
|
+
_animator.SetFloat("Speed", input.magnitude);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Important:** Enable **"Assign Scene On Initialize"** in the `RelationalComponentsInstaller` for automatic scene wiring.
|
|
183
|
+
|
|
184
|
+
### 🟡 Intermediate: "I'm spawning objects at runtime"
|
|
185
|
+
|
|
186
|
+
**Perfect for:** Enemy spawners, projectile systems, object pooling
|
|
187
|
+
|
|
188
|
+
**What you get:** One-line instantiation that handles DI injection + hierarchy wiring automatically
|
|
189
|
+
|
|
190
|
+
**Example:**
|
|
191
|
+
|
|
192
|
+
```csharp
|
|
193
|
+
public sealed class ProjectileSpawner : MonoBehaviour
|
|
194
|
+
{
|
|
195
|
+
private Container _container;
|
|
196
|
+
[SerializeField] private Projectile _projectilePrefab;
|
|
197
|
+
|
|
198
|
+
private void Awake()
|
|
199
|
+
{
|
|
200
|
+
_container = gameObject.scene.GetSceneContainer();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
public Projectile Fire(Vector3 position, Vector3 direction)
|
|
204
|
+
{
|
|
205
|
+
Projectile projectile = _container.InstantiateComponentWithRelations(_projectilePrefab);
|
|
206
|
+
projectile.transform.SetPositionAndRotation(position, Quaternion.LookRotation(direction));
|
|
207
|
+
projectile.Launch(direction);
|
|
208
|
+
return projectile;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 🔴 Advanced: "I have complex hierarchies and custom workflows"
|
|
214
|
+
|
|
215
|
+
**Perfect for:** UI systems, vehicles with multiple parts, procedural generation
|
|
216
|
+
|
|
217
|
+
**What you get:** Full control over when and how wiring happens, with helpers for every scenario
|
|
218
|
+
|
|
219
|
+
**Example - Complex Prefabs:**
|
|
220
|
+
|
|
221
|
+
```csharp
|
|
222
|
+
public sealed class VehicleFactory : MonoBehaviour
|
|
223
|
+
{
|
|
224
|
+
private Container _container;
|
|
225
|
+
[SerializeField] private GameObject _vehiclePrefab;
|
|
226
|
+
|
|
227
|
+
private void Awake()
|
|
228
|
+
{
|
|
229
|
+
_container = gameObject.scene.GetSceneContainer();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
public GameObject CreateVehicle()
|
|
233
|
+
{
|
|
234
|
+
return _container.InstantiateGameObjectWithRelations(
|
|
235
|
+
_vehiclePrefab,
|
|
236
|
+
parent: null,
|
|
237
|
+
includeInactiveChildren: true
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## 💡 Real-World Impact: A Day in the Life
|
|
246
|
+
|
|
247
|
+
### Without This Integration
|
|
248
|
+
|
|
249
|
+
**Morning:** You start work on a new enemy type.
|
|
250
|
+
|
|
251
|
+
```csharp
|
|
252
|
+
public class FlyingEnemy : MonoBehaviour
|
|
253
|
+
{
|
|
254
|
+
[Inject] private IHealthSystem _health;
|
|
255
|
+
[Inject] private IAudioService _audio;
|
|
256
|
+
|
|
257
|
+
private Animator _animator;
|
|
258
|
+
private Rigidbody2D _rigidbody;
|
|
259
|
+
private SpriteRenderer _sprite;
|
|
260
|
+
private Collider2D[] _hitboxes;
|
|
261
|
+
private Transform _weaponMount;
|
|
262
|
+
|
|
263
|
+
void Awake()
|
|
264
|
+
{
|
|
265
|
+
_animator = GetComponent<Animator>();
|
|
266
|
+
if (_animator == null) Debug.LogError("Missing Animator on FlyingEnemy!");
|
|
267
|
+
|
|
268
|
+
_rigidbody = GetComponent<Rigidbody2D>();
|
|
269
|
+
if (_rigidbody == null) Debug.LogError("Missing Rigidbody2D on FlyingEnemy!");
|
|
270
|
+
|
|
271
|
+
_sprite = GetComponent<SpriteRenderer>();
|
|
272
|
+
if (_sprite == null) Debug.LogError("Missing SpriteRenderer on FlyingEnemy!");
|
|
273
|
+
|
|
274
|
+
_hitboxes = GetComponentsInChildren<Collider2D>();
|
|
275
|
+
if (_hitboxes.Length == 0) Debug.LogWarning("No hitboxes found on FlyingEnemy!");
|
|
276
|
+
|
|
277
|
+
_weaponMount = transform.Find("WeaponMount");
|
|
278
|
+
if (_weaponMount == null) Debug.LogError("Missing WeaponMount on FlyingEnemy!");
|
|
279
|
+
|
|
280
|
+
// Finally, actual game logic can start...
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**10 minutes later:** You've written 20+ lines of boilerplate before writing any actual game logic.
|
|
286
|
+
|
|
287
|
+
**30 minutes later:** Null reference exception in the build! You forgot to add the SpriteRenderer to the prefab.
|
|
288
|
+
|
|
289
|
+
**60 minutes later:** You're manually wiring up the 8th enemy variant of the day...
|
|
290
|
+
|
|
291
|
+
### With This Integration
|
|
292
|
+
|
|
293
|
+
**Morning:** You start work on a new enemy type.
|
|
294
|
+
|
|
295
|
+
```csharp
|
|
296
|
+
public class FlyingEnemy : MonoBehaviour
|
|
297
|
+
{
|
|
298
|
+
[Inject] private IHealthSystem _health;
|
|
299
|
+
[Inject] private IAudioService _audio;
|
|
300
|
+
|
|
301
|
+
[SiblingComponent] private Animator _animator;
|
|
302
|
+
[SiblingComponent] private Rigidbody2D _rigidbody;
|
|
303
|
+
[SiblingComponent] private SpriteRenderer _sprite;
|
|
304
|
+
[ChildComponent] private Collider2D[] _hitboxes;
|
|
305
|
+
[ChildComponent(NameFilter = "WeaponMount")] private Transform _weaponMount;
|
|
306
|
+
|
|
307
|
+
// Start writing game logic immediately
|
|
308
|
+
void Start() => _animator.Play("Idle");
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
**2 minutes later:** You're done with wiring and writing game logic.
|
|
313
|
+
|
|
314
|
+
**10 minutes later:** You've shipped 5 enemy variants with zero boilerplate.
|
|
315
|
+
|
|
316
|
+
**Never:** You never see "Missing component" runtime errors because validation happens automatically with helpful messages.
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## 🔧 Advanced Configuration
|
|
321
|
+
|
|
322
|
+
### RelationalComponentsInstaller Options
|
|
323
|
+
|
|
324
|
+
The installer component provides these settings:
|
|
325
|
+
|
|
326
|
+
**Assign Scene On Initialize** *(default: true)*
|
|
327
|
+
|
|
328
|
+
- When enabled, automatically wires all scene components with relational attributes after the container builds
|
|
329
|
+
- Disable if you want to manually control when scene wiring happens
|
|
330
|
+
|
|
331
|
+
**Include Inactive Objects** *(default: true)*
|
|
332
|
+
|
|
333
|
+
- When enabled, scans inactive GameObjects and disabled components
|
|
334
|
+
- Disable to only wire active objects
|
|
335
|
+
|
|
336
|
+
**Listen For Additive Scenes** *(default: false)*
|
|
337
|
+
|
|
338
|
+
- When enabled, automatically wires components in additively loaded scenes
|
|
339
|
+
- Essential for multi-scene workflows
|
|
340
|
+
|
|
341
|
+
**Use Single Pass Scan** *(default: true)*
|
|
342
|
+
|
|
343
|
+
- Uses optimized metadata-driven scanning (faster)
|
|
344
|
+
- Leave enabled unless debugging scan issues
|
|
345
|
+
|
|
346
|
+
### Manual Hierarchy Wiring
|
|
347
|
+
|
|
348
|
+
For dynamic hierarchies or pooled objects:
|
|
349
|
+
|
|
350
|
+
```csharp
|
|
351
|
+
private Container _container;
|
|
352
|
+
|
|
353
|
+
void Awake()
|
|
354
|
+
{
|
|
355
|
+
_container = gameObject.scene.GetSceneContainer();
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
void SetupComplexHierarchy(GameObject root)
|
|
359
|
+
{
|
|
360
|
+
// Wire all components in hierarchy
|
|
361
|
+
_container.AssignRelationalHierarchy(root, includeInactiveChildren: false);
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Performance: Prewarming Reflection Caches
|
|
366
|
+
|
|
367
|
+
For large projects, prewarm reflection caches during loading to avoid first-use stalls:
|
|
368
|
+
|
|
369
|
+
```csharp
|
|
370
|
+
using WallstopStudios.UnityHelpers.Core.Attributes;
|
|
371
|
+
|
|
372
|
+
public class GameBootstrap : MonoBehaviour
|
|
373
|
+
{
|
|
374
|
+
void Awake()
|
|
375
|
+
{
|
|
376
|
+
// Call once during bootstrap/loading screen
|
|
377
|
+
RelationalComponentInitializer.Initialize();
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Or enable auto-prewarm on the `AttributeMetadataCache` asset:
|
|
383
|
+
|
|
384
|
+
1. Create: `Assets > Create > Wallstop Studios > Unity Helpers > Attribute Metadata Cache`
|
|
385
|
+
2. Enable **"Prewarm Relational On Load"** in the Inspector
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## 🧰 Additional Helpers & Recipes
|
|
390
|
+
|
|
391
|
+
### One-liners for DI + Relational Wiring
|
|
392
|
+
|
|
393
|
+
```csharp
|
|
394
|
+
// Inject + assign a single component
|
|
395
|
+
container.InjectWithRelations(component);
|
|
396
|
+
|
|
397
|
+
// Instantiate a component prefab + assign
|
|
398
|
+
var comp = container.InstantiateComponentWithRelations(prefabComp, parent);
|
|
399
|
+
|
|
400
|
+
// Inject + assign a whole hierarchy
|
|
401
|
+
container.InjectGameObjectWithRelations(root, includeInactiveChildren: true);
|
|
402
|
+
|
|
403
|
+
// Instantiate a GameObject prefab + inject + assign hierarchy
|
|
404
|
+
var go = container.InstantiateGameObjectWithRelations(prefabGo, parent);
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Additive Scenes & Options
|
|
408
|
+
|
|
409
|
+
Enable "Listen For Additive Scenes" in the installer, or manually control scene assignment:
|
|
410
|
+
|
|
411
|
+
```csharp
|
|
412
|
+
private Container _container;
|
|
413
|
+
|
|
414
|
+
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
|
415
|
+
{
|
|
416
|
+
if (mode == LoadSceneMode.Additive)
|
|
417
|
+
{
|
|
418
|
+
// Manually wire additive scene
|
|
419
|
+
_container.AssignRelationalScene(scene, includeInactive: true);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## ❓ Troubleshooting
|
|
427
|
+
|
|
428
|
+
### My relational fields are null even with the integration
|
|
429
|
+
|
|
430
|
+
**Check these common issues:**
|
|
431
|
+
|
|
432
|
+
1. **Did you add the installer?**
|
|
433
|
+
- Ensure `RelationalComponentsInstaller` is on your `SceneScope` GameObject
|
|
434
|
+
- Check that it's enabled in the Inspector
|
|
435
|
+
|
|
436
|
+
2. **Scene components not wired?**
|
|
437
|
+
- Enable **"Assign Scene On Initialize"** in the `RelationalComponentsInstaller`
|
|
438
|
+
- Or manually call `_container.AssignRelationalHierarchy(gameObject, includeInactiveChildren: true)` at bootstrap time
|
|
439
|
+
|
|
440
|
+
3. **Are you using the right attributes?**
|
|
441
|
+
- Fields need `[SiblingComponent]`, `[ParentComponent]`, or `[ChildComponent]` attributes
|
|
442
|
+
- These are different from `[Inject]` - you can use both on the same component
|
|
443
|
+
|
|
444
|
+
4. **Runtime instantiation not working?**
|
|
445
|
+
- Use `_container.InstantiateComponentWithRelations(...)`, `_container.InstantiateGameObjectWithRelations(...)`, or `_container.InjectGameObjectWithRelations(...)`
|
|
446
|
+
- Regular `Instantiate()` won't trigger relational wiring without these helpers
|
|
447
|
+
|
|
448
|
+
5. **Check your filters:**
|
|
449
|
+
- `TagFilter` must match an existing Unity tag exactly
|
|
450
|
+
- `NameFilter` is case-sensitive
|
|
451
|
+
|
|
452
|
+
### Do I need to call AssignRelationalComponents() in Awake()?
|
|
453
|
+
|
|
454
|
+
**No!** The integration handles this automatically:
|
|
455
|
+
|
|
456
|
+
- **Scene objects:** Wired when you enable "Assign Scene On Initialize" (recommended)
|
|
457
|
+
- **Runtime objects:** Wired when you call any of the helper methods (`InstantiateComponentWithRelations`, `InstantiateGameObjectWithRelations`, or `InjectGameObjectWithRelations`)
|
|
458
|
+
|
|
459
|
+
Only call `AssignRelationalComponents()` manually if you need fine-grained control.
|
|
460
|
+
|
|
461
|
+
### Does this work without Reflex?
|
|
462
|
+
|
|
463
|
+
**Yes!** The integration gracefully falls back to standard Unity Helpers behavior if Reflex isn't detected. You can:
|
|
464
|
+
|
|
465
|
+
- Adopt incrementally without breaking existing code
|
|
466
|
+
- Use in projects that mix DI and non-DI components
|
|
467
|
+
- Remove Reflex later without refactoring all your components
|
|
468
|
+
|
|
469
|
+
### Performance impact?
|
|
470
|
+
|
|
471
|
+
**Minimal:** Relational component assignment happens once per component at initialization time. After that, there's zero runtime overhead - the references are just regular fields.
|
|
472
|
+
|
|
473
|
+
**Optimization tips:**
|
|
474
|
+
|
|
475
|
+
- Use `MaxDepth` to limit hierarchy traversal
|
|
476
|
+
- Use `TagFilter` or `NameFilter` to narrow searches
|
|
477
|
+
- Use `OnlyDescendants`/`OnlyAncestors` to exclude self when appropriate
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## 📚 Learn More
|
|
482
|
+
|
|
483
|
+
**Unity Helpers Documentation:**
|
|
484
|
+
|
|
485
|
+
- [Relational Components Guide](../../Docs/RELATIONAL_COMPONENTS.md) - Complete attribute reference and recipes
|
|
486
|
+
- [Getting Started](../../Docs/GETTING_STARTED.md) - Unity Helpers quick start guide
|
|
487
|
+
- [Main README](../../README.md) - Full feature overview
|
|
488
|
+
|
|
489
|
+
**Reflex Documentation:**
|
|
490
|
+
|
|
491
|
+
- [Reflex GitHub](https://github.com/gustavopsantos/reflex) - Official Reflex documentation and source code
|
|
492
|
+
|
|
493
|
+
**Troubleshooting:**
|
|
494
|
+
|
|
495
|
+
- [Relational Components Troubleshooting](../../Docs/RELATIONAL_COMPONENTS.md#troubleshooting) - Detailed solutions
|
|
496
|
+
- [DI Integration Testing Guide](../../Docs/RELATIONAL_COMPONENTS.md#di-integrations-testing-and-edge-cases) - Advanced scenarios
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## 🎓 Next Steps
|
|
501
|
+
|
|
502
|
+
1. **Try the sample scene:** Open `Reflex_Sample.unity` and press Play
|
|
503
|
+
2. **Read the scripts:** See how `ReflexSpawner` and `ReflexRelationalConsumer` work
|
|
504
|
+
3. **Add to your project:** Add `RelationalComponentsInstaller` to your `SceneScope`
|
|
505
|
+
4. **Explore attributes:** Check out the [Relational Components Guide](../../Docs/RELATIONAL_COMPONENTS.md) for all options
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
## 🔄 Comparison: Reflex vs VContainer vs Zenject Integration
|
|
510
|
+
|
|
511
|
+
If you're choosing between DI frameworks, here's how the integrations differ:
|
|
512
|
+
|
|
513
|
+
| Feature | Reflex | VContainer | Zenject |
|
|
514
|
+
|---------|--------|------------|---------|
|
|
515
|
+
| Setup | Add installer to SceneScope | Call in LifetimeScope.Configure() | Add installer to SceneContext |
|
|
516
|
+
| Scene wiring | Toggle on installer | Automatic | Toggle on installer |
|
|
517
|
+
| Runtime instantiation | `InstantiateComponentWithRelations()`, `InstantiateGameObjectWithRelations()` | `InstantiateComponentWithRelations()`, `InstantiateGameObjectWithRelations()`, `BuildUpWithRelations()` | `InstantiateComponentWithRelations()`, `InstantiateGameObjectWithRelations()` |
|
|
518
|
+
| Performance | Fast | Slightly faster | Good |
|
|
519
|
+
| Maintenance | Actively developed | Actively developed | Community-maintained |
|
|
520
|
+
|
|
521
|
+
All three integrations provide the same relational component features - choose based on your DI framework preference.
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## Made with ❤️ by Wallstop Studios
|
|
526
|
+
|
|
527
|
+
*Unity Helpers is production-ready and actively maintained. [Star the repo](https://github.com/wallstop/unity-helpers) if you find it useful!*
|