com.wallstop-studios.unity-helpers 2.0.0-rc81.6 → 2.0.0-rc81.9
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/.config/dotnet-tools.json +10 -10
- package/.csharpierignore +1 -0
- package/.csharpierrc.json +3 -0
- package/.editorconfig +184 -184
- package/.gitattributes +87 -63
- package/.githooks/pre-commit +49 -0
- package/.github/dependabot.yml +9 -9
- package/.github/workflows/csharpier.yml +135 -0
- package/.github/workflows/lint-doc-links.yml +27 -0
- package/.github/workflows/markdown-json.yml +41 -0
- package/.github/workflows/npm-publish.yml +75 -75
- package/.lychee.toml +26 -0
- package/.markdownlint.json +21 -0
- package/.markdownlintignore +8 -0
- package/.pre-commit-config.yaml +39 -22
- package/.prettierignore +22 -0
- package/.prettierrc.json +20 -0
- package/AGENTS.md +52 -0
- package/{Third Party Notices.md.meta → AGENTS.md.meta} +7 -7
- package/CHANGELOG.md.meta +7 -7
- package/DATA_STRUCTURES.md +324 -0
- package/DATA_STRUCTURES.md.meta +7 -0
- package/Docs/Images/attribute_resolution.svg +40 -0
- package/Docs/Images/attribute_resolution.svg.meta +7 -0
- package/Docs/Images/bitset.svg +47 -0
- package/Docs/Images/bitset.svg.meta +7 -0
- package/Docs/Images/concave_hull.svg +30 -0
- package/Docs/Images/concave_hull.svg.meta +7 -0
- package/Docs/Images/convex_hull.svg +29 -0
- package/Docs/Images/convex_hull.svg.meta +7 -0
- package/Docs/Images/cyclic_buffer.svg +37 -0
- package/Docs/Images/cyclic_buffer.svg.meta +7 -0
- package/Docs/Images/data_distribution_decision.svg +88 -0
- package/Docs/Images/data_distribution_decision.svg.meta +7 -0
- package/Docs/Images/deque.svg +64 -0
- package/Docs/Images/deque.svg.meta +7 -0
- package/Docs/Images/deque_queue.svg +107 -0
- package/Docs/Images/deque_queue.svg.meta +7 -0
- package/Docs/Images/disjoint_set.svg +47 -0
- package/Docs/Images/disjoint_set.svg.meta +7 -0
- package/Docs/Images/effects_pipeline.svg +59 -0
- package/Docs/Images/effects_pipeline.svg.meta +7 -0
- package/Docs/Images/geometry_edge_cases.svg +61 -0
- package/Docs/Images/geometry_edge_cases.svg.meta +7 -0
- package/Docs/Images/heap.svg +56 -0
- package/Docs/Images/heap.svg.meta +7 -0
- package/Docs/Images/kdtree_2d.svg +38 -0
- package/Docs/Images/kdtree_2d.svg.meta +7 -0
- package/Docs/Images/kdtree_3d.svg +83 -0
- package/Docs/Images/kdtree_3d.svg.meta +7 -0
- package/Docs/Images/octree_3d.svg +79 -0
- package/Docs/Images/octree_3d.svg.meta +7 -0
- package/Docs/Images/polyline_simplify.svg +18 -0
- package/Docs/Images/polyline_simplify.svg.meta +7 -0
- package/Docs/Images/quadtree_2d.svg +37 -0
- package/Docs/Images/quadtree_2d.svg.meta +7 -0
- package/Docs/Images/query_boundaries.svg +38 -0
- package/Docs/Images/query_boundaries.svg.meta +7 -0
- package/Docs/Images/random_generators.svg +105 -0
- package/Docs/Images/random_generators.svg.meta +7 -0
- package/Docs/Images/reflection_scan.svg +33 -0
- package/Docs/Images/reflection_scan.svg.meta +7 -0
- package/Docs/Images/relational_wiring.svg +75 -0
- package/Docs/Images/relational_wiring.svg.meta +7 -0
- package/Docs/Images/rtree_2d.svg +27 -0
- package/Docs/Images/rtree_2d.svg.meta +7 -0
- package/Docs/Images/rtree_3d.svg +79 -0
- package/Docs/Images/rtree_3d.svg.meta +7 -0
- package/Docs/Images/serialization_flow.svg +50 -0
- package/Docs/Images/serialization_flow.svg.meta +7 -0
- package/Docs/Images/singletons_lifecycle.svg +54 -0
- package/Docs/Images/singletons_lifecycle.svg.meta +7 -0
- package/Docs/Images/sparse_set.svg +54 -0
- package/Docs/Images/sparse_set.svg.meta +7 -0
- package/Docs/Images/trie.svg +55 -0
- package/Docs/Images/trie.svg.meta +7 -0
- package/Docs/Images.meta +8 -0
- package/Docs.meta +8 -0
- package/EDITOR_TOOLS_GUIDE.md +1976 -0
- package/EDITOR_TOOLS_GUIDE.md.meta +7 -0
- package/EFFECTS_SYSTEM.md +242 -0
- package/EFFECTS_SYSTEM.md.meta +7 -0
- package/EFFECTS_SYSTEM_TUTORIAL.md +467 -0
- package/EFFECTS_SYSTEM_TUTORIAL.md.meta +7 -0
- package/Editor/AnimationEventEditor.cs +1393 -874
- package/Editor/AnimationEventEditor.cs.meta +11 -11
- package/Editor/AssemblyInfo.cs +4 -0
- package/Editor/AssemblyInfo.cs.meta +3 -0
- package/Editor/AssetProcessors/SpriteLabelProcessor.cs +138 -111
- package/Editor/AssetProcessors/SpriteLabelProcessor.cs.meta +2 -2
- package/Editor/AssetProcessors.meta +2 -2
- package/Editor/Core/Helper/AnimationEventHelpers.cs +204 -0
- package/{Runtime/Core/DataStructure/ISpatialTree.cs.meta → Editor/Core/Helper/AnimationEventHelpers.cs.meta} +11 -11
- package/Editor/Core/Helper.meta +8 -0
- package/Editor/Core.meta +8 -0
- package/Editor/CustomDrawers/IntDropdownDrawer.cs +46 -46
- package/Editor/CustomDrawers/IntDropdownDrawer.cs.meta +2 -2
- package/Editor/CustomDrawers/StringInListeDrawer.cs +135 -135
- package/Editor/CustomDrawers/StringInListeDrawer.cs.meta +2 -2
- package/Editor/CustomDrawers/WShowIfPropertyDrawer.cs +105 -105
- package/Editor/CustomDrawers/WShowIfPropertyDrawer.cs.meta +2 -2
- package/Editor/CustomDrawers.meta +2 -2
- package/Editor/CustomEditors/MatchColliderToSpriteEditor.cs +32 -32
- package/Editor/CustomEditors/MatchColliderToSpriteEditor.cs.meta +2 -2
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs +799 -799
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs.meta +2 -2
- package/Editor/CustomEditors/PolygonCollider2DOptimizerEditor.cs +38 -40
- package/Editor/CustomEditors/PolygonCollider2DOptimizerEditor.cs.meta +2 -2
- package/Editor/CustomEditors/SourceFolderEntryDrawer.cs +685 -413
- package/Editor/CustomEditors/SourceFolderEntryDrawer.cs.meta +2 -2
- package/Editor/CustomEditors/TexturePlatformOverrideEntryDrawer.cs +146 -0
- package/{Runtime/Core/DataStructure/KDTree.cs.meta → Editor/CustomEditors/TexturePlatformOverrideEntryDrawer.cs.meta} +11 -11
- package/Editor/CustomEditors.meta +2 -2
- package/Editor/Extensions/SerializedPropertyExtensions.cs +217 -190
- package/Editor/Extensions/SerializedPropertyExtensions.cs.meta +2 -2
- package/Editor/Extensions/UnityExtensions.cs +50 -26
- package/Editor/Extensions/UnityExtensions.cs.meta +2 -2
- package/Editor/Extensions.meta +2 -2
- package/Editor/FitTextureSizeWindow.cs +785 -332
- package/Editor/FitTextureSizeWindow.cs.meta +2 -2
- package/Editor/Persistence/MultiFileSelectorPersistenceManager.cs +62 -0
- package/{Runtime/Core/DataStructure/QuadTree.cs.meta → Editor/Persistence/MultiFileSelectorPersistenceManager.cs.meta} +11 -11
- package/Editor/Persistence/MultiFileSelectorPersistenceWindow.cs +65 -0
- package/Editor/Persistence/MultiFileSelectorPersistenceWindow.cs.meta +11 -0
- package/Editor/Persistence.meta +8 -0
- package/Editor/PersistentDirectorySettings.cs +529 -248
- package/Editor/PersistentDirectorySettings.cs.meta +2 -2
- package/Editor/PrefabChecker.cs +1329 -741
- package/Editor/PrefabChecker.cs.meta +11 -11
- package/Editor/Sprites/AnimationCopier.cs +1518 -789
- package/Editor/Sprites/AnimationCopier.cs.meta +2 -2
- package/Editor/Sprites/AnimationCreator.cs +1532 -881
- package/Editor/Sprites/AnimationCreator.cs.meta +11 -11
- package/Editor/Sprites/AnimationViewerWindow.cs +1634 -1522
- package/Editor/Sprites/AnimationViewerWindow.cs.meta +2 -2
- package/Editor/Sprites/ScriptableSpriteAtlas.cs +251 -178
- package/Editor/Sprites/ScriptableSpriteAtlas.cs.meta +2 -2
- package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs +1470 -1026
- package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs.meta +2 -2
- package/Editor/Sprites/SpriteCropper.cs +1013 -523
- package/Editor/Sprites/SpriteCropper.cs.meta +2 -2
- package/Editor/Sprites/SpritePivotAdjustor.cs +605 -265
- package/Editor/Sprites/SpritePivotAdjustor.cs.meta +2 -2
- package/Editor/Sprites/SpriteSettingsApplier.cs +942 -918
- package/Editor/Sprites/SpriteSettingsApplier.cs.meta +2 -2
- package/Editor/Sprites/SpriteSettingsApplierAPI.cs +441 -0
- package/Editor/Sprites/SpriteSettingsApplierAPI.cs.meta +11 -0
- package/Editor/Sprites/SpriteSettingsProfileCollection.cs +12 -0
- package/Editor/Sprites/SpriteSettingsProfileCollection.cs.meta +11 -0
- package/Editor/Sprites/SpriteSheetAnimationCreator.cs +1586 -1537
- package/Editor/Sprites/SpriteSheetAnimationCreator.cs.meta +2 -2
- package/Editor/Sprites/TexturePlatformNameHelper.cs +78 -0
- package/Editor/Sprites/TexturePlatformNameHelper.cs.meta +11 -0
- package/Editor/Sprites/TextureResizerWizard.cs +434 -175
- package/Editor/Sprites/TextureResizerWizard.cs.meta +2 -2
- package/Editor/Sprites/TextureSettingsApplierAPI.cs +359 -0
- package/Editor/Sprites/TextureSettingsApplierAPI.cs.meta +11 -0
- package/Editor/Sprites/TextureSettingsApplierWindow.cs +605 -0
- package/Editor/Sprites/TextureSettingsApplierWindow.cs.meta +11 -0
- package/Editor/Sprites.meta +2 -2
- package/Editor/Styles/AnimationViewer.uss +115 -115
- package/Editor/Styles/AnimationViewer.uss.meta +2 -2
- package/Editor/Styles/AnimationViewer.uxml +56 -56
- package/Editor/Styles/AnimationViewer.uxml.meta +2 -2
- package/Editor/Styles/SpriteSheetAnimationCreator.uss +10 -0
- package/Editor/Styles/SpriteSheetAnimationCreator.uss.meta +11 -0
- package/Editor/Styles.meta +2 -2
- package/Editor/Tags/AttributeMetadataCacheEditor.cs +46 -0
- package/Editor/Tags/AttributeMetadataCacheEditor.cs.meta +11 -0
- package/Editor/Tags/AttributeMetadataCacheGenerator.cs +258 -0
- package/Editor/Tags/AttributeMetadataCacheGenerator.cs.meta +11 -0
- package/Editor/Tags.meta +8 -0
- package/Editor/Tools/ImageBlurTool.cs +451 -409
- package/Editor/Tools/ImageBlurTool.cs.meta +2 -2
- package/Editor/Tools.meta +2 -2
- package/Editor/Utils/DxReadOnlyPropertyDrawer.cs +26 -26
- package/Editor/Utils/DxReadOnlyPropertyDrawer.cs.meta +11 -11
- package/Editor/Utils/EditorUi.cs +228 -0
- package/Editor/Utils/EditorUi.cs.meta +11 -0
- package/Editor/Utils/EditorUtilities.cs +22 -22
- package/Editor/Utils/EditorUtilities.cs.meta +11 -11
- package/Editor/Utils/ScriptableObjectSingletonCreator.cs +633 -52
- package/Editor/Utils/ScriptableObjectSingletonCreator.cs.meta +2 -2
- package/Editor/Utils.meta +8 -8
- package/Editor/Visuals/EnhancedImageEditor.cs +160 -160
- package/Editor/Visuals/EnhancedImageEditor.cs.meta +11 -11
- package/Editor/Visuals.meta +2 -2
- package/Editor/WallstopStudios.UnityHelpers.Editor.asmdef +14 -18
- package/Editor/WallstopStudios.UnityHelpers.Editor.asmdef.meta +7 -7
- package/Editor.meta +8 -8
- package/GETTING_STARTED.md +425 -0
- package/GETTING_STARTED.md.meta +7 -0
- package/GLOSSARY.md +313 -0
- package/GLOSSARY.md.meta +7 -0
- package/HULLS.md +45 -0
- package/HULLS.md.meta +7 -0
- package/INDEX.md +429 -0
- package/INDEX.md.meta +7 -0
- package/LICENSE +21 -21
- package/LICENSE.md +7 -7
- package/LICENSE.md.meta +7 -7
- package/LICENSE.meta +7 -7
- package/MATH_AND_EXTENSIONS.md +316 -0
- package/MATH_AND_EXTENSIONS.md.meta +7 -0
- package/RANDOM_PERFORMANCE.md +140 -0
- package/RANDOM_PERFORMANCE.md.meta +7 -0
- package/README.md +3195 -188
- package/README.md.meta +7 -7
- package/REFLECTION_HELPERS.md +272 -0
- package/REFLECTION_HELPERS.md.meta +7 -0
- package/RELATIONAL_COMPONENTS.md +543 -0
- package/RELATIONAL_COMPONENTS.md.meta +7 -0
- package/Runtime/AssemblyInfo.cs +7 -0
- package/Runtime/AssemblyInfo.cs.meta +11 -0
- package/Runtime/Binaries/Microsoft.Bcl.AsyncInterfaces.dll +0 -0
- package/Runtime/Binaries/Microsoft.Bcl.AsyncInterfaces.dll.meta +33 -33
- package/Runtime/Binaries/Microsoft.Bcl.AsyncInterfaces.xml +499 -278
- package/Runtime/Binaries/Microsoft.Bcl.AsyncInterfaces.xml.meta +7 -7
- package/Runtime/Binaries/System.IO.Pipelines.dll +0 -0
- package/Runtime/Binaries/System.IO.Pipelines.dll.meta +33 -0
- package/Runtime/Binaries/System.IO.Pipelines.xml +702 -0
- package/Runtime/Binaries/System.IO.Pipelines.xml.meta +7 -0
- package/Runtime/Binaries/System.Text.Encodings.Web.dll +0 -0
- package/Runtime/Binaries/System.Text.Encodings.Web.dll.meta +33 -33
- package/Runtime/Binaries/System.Text.Encodings.Web.xml +1084 -1079
- package/Runtime/Binaries/System.Text.Encodings.Web.xml.meta +7 -7
- package/Runtime/Binaries/System.Text.Json.dll +0 -0
- package/Runtime/Binaries/System.Text.Json.dll.meta +33 -33
- package/Runtime/Binaries/System.Text.Json.xml +10217 -8116
- package/Runtime/Binaries/System.Text.Json.xml.meta +7 -7
- package/Runtime/Binaries.meta +8 -8
- package/Runtime/Core/Attributes/AnimationEventAttribute.cs +10 -138
- package/Runtime/Core/Attributes/AnimationEventAttribute.cs.meta +11 -11
- package/Runtime/Core/Attributes/BaseRelationalComponentAttribute.cs +841 -0
- package/Runtime/Core/Attributes/BaseRelationalComponentAttribute.cs.meta +11 -0
- package/Runtime/Core/Attributes/ChildComponentAttribute.cs +284 -226
- package/Runtime/Core/Attributes/ChildComponentAttribute.cs.meta +11 -11
- package/Runtime/Core/Attributes/DxReadOnlyAttribute.cs +6 -6
- package/Runtime/Core/Attributes/DxReadOnlyAttribute.cs.meta +11 -11
- package/Runtime/Core/Attributes/EnumDisplayNameAttribute.cs +15 -15
- package/Runtime/Core/Attributes/EnumDisplayNameAttribute.cs.meta +2 -2
- package/Runtime/Core/Attributes/IRelationalComponentAssigner.cs +36 -0
- package/Runtime/Core/Attributes/IRelationalComponentAssigner.cs.meta +11 -0
- package/Runtime/Core/Attributes/IntDropdownAttribute.cs +14 -14
- package/Runtime/Core/Attributes/IntDropdownAttribute.cs.meta +2 -2
- package/Runtime/Core/Attributes/KSerializableAttribute.cs +19 -19
- package/Runtime/Core/Attributes/KSerializableAttribute.cs.meta +11 -11
- package/Runtime/Core/Attributes/NotNullAttribute.cs +32 -32
- package/Runtime/Core/Attributes/NotNullAttribute.cs.meta +11 -11
- package/Runtime/Core/Attributes/ParentComponentAttribute.cs +376 -0
- package/Runtime/Core/Attributes/{ParentComponent.cs.meta → ParentComponentAttribute.cs.meta} +11 -11
- package/Runtime/Core/Attributes/RelationalComponentAssigner.cs +107 -0
- package/Runtime/Core/Attributes/RelationalComponentAssigner.cs.meta +11 -0
- package/Runtime/Core/Attributes/RelationalComponentExtensions.cs +61 -14
- package/Runtime/Core/Attributes/RelationalComponentExtensions.cs.meta +11 -11
- package/Runtime/Core/Attributes/RelationalComponentInitializer.cs +331 -0
- package/Runtime/Core/Attributes/RelationalComponentInitializer.cs.meta +11 -0
- package/Runtime/Core/Attributes/ScriptableSingletonPathAttribute.cs +15 -15
- package/Runtime/Core/Attributes/ScriptableSingletonPathAttribute.cs.meta +2 -2
- package/Runtime/Core/Attributes/SiblingComponentAttribute.cs +264 -137
- package/Runtime/Core/Attributes/SiblingComponentAttribute.cs.meta +11 -11
- package/Runtime/Core/Attributes/ValidateAssignmentAttribute.cs +115 -106
- package/Runtime/Core/Attributes/ValidateAssignmentAttribute.cs.meta +11 -11
- package/Runtime/Core/Attributes/ValueHelpers.cs +10 -0
- package/Runtime/Core/Attributes/ValueHelpers.cs.meta +3 -0
- package/Runtime/Core/Attributes/WShowIfAttribute.cs +24 -24
- package/Runtime/Core/Attributes/WShowIfAttribute.cs.meta +2 -2
- package/Runtime/Core/Attributes.meta +8 -8
- package/Runtime/Core/DataStructure/Adapters/FastVector2Int.cs +192 -92
- package/Runtime/Core/DataStructure/Adapters/FastVector2Int.cs.meta +11 -11
- package/Runtime/Core/DataStructure/Adapters/FastVector3Int.cs +268 -185
- package/Runtime/Core/DataStructure/Adapters/FastVector3Int.cs.meta +11 -11
- package/Runtime/Core/DataStructure/Adapters/KGuid.cs +360 -305
- package/Runtime/Core/DataStructure/Adapters/KGuid.cs.meta +11 -11
- package/Runtime/Core/DataStructure/Adapters/KVector2.cs +146 -80
- package/Runtime/Core/DataStructure/Adapters/KVector2.cs.meta +11 -11
- package/Runtime/Core/DataStructure/Adapters.meta +8 -8
- package/Runtime/Core/DataStructure/BitSet.cs +626 -0
- package/Runtime/Core/DataStructure/BitSet.cs.meta +11 -0
- package/Runtime/Core/DataStructure/BoundingBox3D.cs +405 -0
- package/Runtime/Core/DataStructure/BoundingBox3D.cs.meta +11 -0
- package/Runtime/Core/DataStructure/Circle.cs +203 -50
- package/Runtime/Core/DataStructure/Circle.cs.meta +11 -11
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +489 -266
- package/Runtime/Core/DataStructure/CyclicBuffer.cs.meta +11 -11
- package/Runtime/Core/DataStructure/Deque.cs +561 -0
- package/Runtime/Core/DataStructure/Deque.cs.meta +11 -0
- package/Runtime/Core/DataStructure/DisjointSet.cs +483 -0
- package/Runtime/Core/DataStructure/DisjointSet.cs.meta +11 -0
- package/Runtime/Core/DataStructure/Heap.cs +514 -0
- package/Runtime/Core/DataStructure/Heap.cs.meta +11 -0
- package/Runtime/Core/DataStructure/{ISpatialTree.cs → ISpatialTree2D.cs} +25 -21
- package/Runtime/Core/DataStructure/ISpatialTree2D.cs.meta +11 -0
- package/Runtime/Core/DataStructure/ISpatialTree3D.cs +33 -0
- package/Runtime/Core/DataStructure/ISpatialTree3D.cs.meta +11 -0
- package/Runtime/Core/DataStructure/ImmutableBitSet.cs +398 -0
- package/Runtime/Core/DataStructure/ImmutableBitSet.cs.meta +3 -0
- package/Runtime/Core/DataStructure/KDTree2D.cs +852 -0
- package/Runtime/Core/DataStructure/KDTree2D.cs.meta +11 -0
- package/Runtime/Core/DataStructure/KDTree3D.cs +911 -0
- package/Runtime/Core/DataStructure/KDTree3D.cs.meta +11 -0
- package/Runtime/Core/DataStructure/OctTree3D.cs +983 -0
- package/Runtime/Core/DataStructure/OctTree3D.cs.meta +11 -0
- package/Runtime/Core/DataStructure/PriorityQueue.cs +194 -0
- package/Runtime/Core/DataStructure/PriorityQueue.cs.meta +11 -0
- package/Runtime/Core/DataStructure/QuadTree2D.cs +722 -0
- package/Runtime/Core/DataStructure/QuadTree2D.cs.meta +11 -0
- package/Runtime/Core/DataStructure/RTree2D.cs +704 -0
- package/Runtime/Core/DataStructure/{RTree.cs.meta → RTree2D.cs.meta} +11 -11
- package/Runtime/Core/DataStructure/RTree3D.cs +775 -0
- package/Runtime/Core/DataStructure/RTree3D.cs.meta +11 -0
- package/Runtime/Core/DataStructure/SparseSet.cs +597 -0
- package/Runtime/Core/DataStructure/SparseSet.cs.meta +11 -0
- package/Runtime/Core/DataStructure/SpatialHash2D.cs +312 -0
- package/Runtime/Core/DataStructure/SpatialHash2D.cs.meta +3 -0
- package/Runtime/Core/DataStructure/SpatialHash3D.cs +341 -0
- package/Runtime/Core/DataStructure/SpatialHash3D.cs.meta +11 -0
- package/Runtime/Core/DataStructure/Sphere.cs +264 -0
- package/Runtime/Core/DataStructure/Sphere.cs.meta +11 -0
- package/Runtime/Core/DataStructure/StringWrapper.cs +115 -91
- package/Runtime/Core/DataStructure/StringWrapper.cs.meta +11 -11
- package/Runtime/Core/DataStructure/TimedCache.cs +88 -66
- package/Runtime/Core/DataStructure/TimedCache.cs.meta +11 -11
- package/Runtime/Core/DataStructure/Trie.cs +660 -359
- package/Runtime/Core/DataStructure/Trie.cs.meta +2 -2
- package/Runtime/Core/DataStructure.meta +8 -8
- package/Runtime/Core/Extension/AnimatorExtensions.cs +40 -25
- package/Runtime/Core/Extension/AnimatorExtensions.cs.meta +11 -11
- package/Runtime/Core/Extension/AsyncOperationExtensions.cs +404 -110
- package/Runtime/Core/Extension/AsyncOperationExtensions.cs.meta +2 -2
- package/Runtime/Core/Extension/CircleExtensions.cs +125 -25
- package/Runtime/Core/Extension/CircleExtensions.cs.meta +11 -11
- package/Runtime/Core/Extension/ColorExtensions.cs +983 -644
- package/Runtime/Core/Extension/ColorExtensions.cs.meta +11 -11
- package/Runtime/Core/Extension/DictionaryExtensions.cs +606 -299
- package/Runtime/Core/Extension/DictionaryExtensions.cs.meta +11 -11
- package/Runtime/Core/Extension/DirectionExtensions.cs +377 -213
- package/Runtime/Core/Extension/DirectionExtensions.cs.meta +11 -11
- package/Runtime/Core/Extension/EnumExtensions.cs +535 -137
- package/Runtime/Core/Extension/EnumExtensions.cs.meta +2 -2
- package/Runtime/Core/Extension/IEnumerableExtensions.cs +341 -124
- package/Runtime/Core/Extension/IEnumerableExtensions.cs.meta +11 -11
- package/Runtime/Core/Extension/IListExtensions.cs +767 -248
- package/Runtime/Core/Extension/IListExtensions.cs.meta +11 -11
- package/Runtime/Core/Extension/IReadonlyListExtensions.cs +687 -37
- package/Runtime/Core/Extension/IReadonlyListExtensions.cs.meta +2 -2
- package/Runtime/Core/Extension/ProtoEqualityExtensions.cs +292 -0
- package/Runtime/Core/Extension/ProtoEqualityExtensions.cs.meta +3 -0
- package/Runtime/Core/Extension/RandomExtensions.cs +938 -109
- package/Runtime/Core/Extension/RandomExtensions.cs.meta +11 -11
- package/Runtime/Core/Extension/StringExtensions.cs +1635 -239
- package/Runtime/Core/Extension/StringExtensions.cs.meta +11 -11
- package/Runtime/Core/Extension/UnityExtensions.cs +4555 -1689
- package/Runtime/Core/Extension/UnityExtensions.cs.meta +11 -11
- package/Runtime/Core/Extension/WallstopStudiosLogger.cs +271 -245
- package/Runtime/Core/Extension/WallstopStudiosLogger.cs.meta +11 -11
- package/Runtime/Core/Extension.meta +8 -8
- package/Runtime/Core/Helper/ArrayConverter.cs +73 -39
- package/Runtime/Core/Helper/ArrayConverter.cs.meta +2 -2
- package/Runtime/Core/Helper/AssignUtilities.cs +33 -14
- package/Runtime/Core/Helper/AssignUtilities.cs.meta +11 -11
- package/Runtime/Core/Helper/DirectoryHelper.cs +210 -196
- package/Runtime/Core/Helper/DirectoryHelper.cs.meta +2 -2
- package/Runtime/Core/Helper/Enumerables.cs +51 -17
- package/Runtime/Core/Helper/Enumerables.cs.meta +11 -11
- package/Runtime/Core/Helper/FileHelper.cs +97 -77
- package/Runtime/Core/Helper/FileHelper.cs.meta +2 -2
- package/Runtime/Core/Helper/FormattingHelpers.cs +49 -38
- package/Runtime/Core/Helper/FormattingHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/FuncBasedComparer.cs +29 -0
- package/Runtime/Core/Helper/FuncBasedComparer.cs.meta +3 -0
- package/Runtime/Core/Helper/Geometry.cs +65 -43
- package/Runtime/Core/Helper/Geometry.cs.meta +11 -11
- package/Runtime/Core/Helper/Helpers.cs +1271 -831
- package/Runtime/Core/Helper/Helpers.cs.meta +11 -11
- package/Runtime/Core/Helper/IterationHelpers.cs +83 -32
- package/Runtime/Core/Helper/IterationHelpers.cs.meta +11 -11
- package/Runtime/Core/Helper/LifetimeHelpers.cs +20 -13
- package/Runtime/Core/Helper/LifetimeHelpers.cs.meta +11 -11
- package/Runtime/Core/Helper/LineHelper.cs +259 -194
- package/Runtime/Core/Helper/LineHelper.cs.meta +2 -2
- package/Runtime/Core/Helper/Logging/UnityLogTagFormatter.cs +549 -539
- package/Runtime/Core/Helper/Logging/UnityLogTagFormatter.cs.meta +2 -2
- package/Runtime/Core/Helper/Logging.meta +2 -2
- package/Runtime/Core/Helper/Objects.cs +477 -769
- package/Runtime/Core/Helper/Objects.cs.meta +11 -11
- package/Runtime/Core/Helper/Partials/LogHelpers.cs +13 -13
- package/Runtime/Core/Helper/Partials/LogHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/Partials/MathHelpers.cs +45 -30
- package/Runtime/Core/Helper/Partials/MathHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +506 -400
- package/Runtime/Core/Helper/Partials/ObjectHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/Partials/TransformHelpers.cs +393 -377
- package/Runtime/Core/Helper/Partials/TransformHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/Partials.meta +2 -2
- package/Runtime/Core/Helper/PathHelper.cs +42 -15
- package/Runtime/Core/Helper/PathHelper.cs.meta +2 -2
- package/Runtime/Core/Helper/ReflectionHelpers.cs +5287 -1963
- package/Runtime/Core/Helper/ReflectionHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/ReverseComparer.cs +33 -0
- package/Runtime/Core/Helper/ReverseComparer.cs.meta +3 -0
- package/Runtime/Core/Helper/SceneHelper.cs +251 -224
- package/Runtime/Core/Helper/SceneHelper.cs.meta +2 -2
- package/Runtime/Core/Helper/SpriteHelpers.cs +50 -41
- package/Runtime/Core/Helper/SpriteHelpers.cs.meta +11 -11
- package/Runtime/Core/Helper/StringInList.cs +61 -35
- package/Runtime/Core/Helper/StringInList.cs.meta +11 -11
- package/Runtime/Core/Helper/TestAssemblyHelper.cs +134 -0
- package/Runtime/Core/Helper/TestAssemblyHelper.cs.meta +11 -0
- package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs +100 -82
- package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs.meta +2 -2
- package/Runtime/Core/Helper/WallMath.cs +672 -166
- package/Runtime/Core/Helper/WallMath.cs.meta +11 -11
- package/Runtime/Core/Helper.meta +8 -8
- package/Runtime/Core/Math/Line2D.cs +263 -0
- package/Runtime/Core/Math/Line2D.cs.meta +11 -0
- package/Runtime/Core/Math/Line3D.cs +452 -0
- package/Runtime/Core/Math/Line3D.cs.meta +11 -0
- package/Runtime/Core/Math/Parabola.cs +241 -47
- package/Runtime/Core/Math/Parabola.cs.meta +11 -11
- package/Runtime/Core/Math/PointPolygonCheck.cs +175 -36
- package/Runtime/Core/Math/PointPolygonCheck.cs.meta +11 -11
- package/Runtime/Core/Math/Range.cs +157 -92
- package/Runtime/Core/Math/Range.cs.meta +11 -11
- package/Runtime/Core/Math.meta +8 -8
- package/Runtime/Core/Model/Direction.cs +25 -43
- package/Runtime/Core/Model/Direction.cs.meta +11 -11
- package/Runtime/Core/Model.meta +8 -8
- package/Runtime/Core/OneOf/FastOneOf.cs +252 -152
- package/Runtime/Core/OneOf/FastOneOf.cs.meta +11 -11
- package/Runtime/Core/OneOf/FastOneOf2.cs +198 -0
- package/Runtime/Core/OneOf/FastOneOf2.cs.meta +11 -0
- package/Runtime/Core/OneOf/FastOneOf4.cs +324 -0
- package/Runtime/Core/OneOf/FastOneOf4.cs.meta +11 -0
- package/Runtime/Core/OneOf/None.cs +30 -4
- package/Runtime/Core/OneOf/None.cs.meta +11 -11
- package/Runtime/Core/OneOf.meta +8 -8
- package/Runtime/Core/Random/AbstractRandom.cs +1318 -655
- package/Runtime/Core/Random/AbstractRandom.cs.meta +11 -11
- package/Runtime/Core/Random/DotNetRandom.cs +118 -54
- package/Runtime/Core/Random/DotNetRandom.cs.meta +2 -2
- package/Runtime/Core/Random/IRandom.cs +203 -161
- package/Runtime/Core/Random/IRandom.cs.meta +11 -11
- package/Runtime/Core/Random/IllusionFlow.cs +171 -107
- package/Runtime/Core/Random/IllusionFlow.cs.meta +2 -2
- package/Runtime/Core/Random/LinearCongruentialGenerator.cs +90 -49
- package/Runtime/Core/Random/LinearCongruentialGenerator.cs.meta +2 -2
- package/Runtime/Core/Random/NativePcgRandom.cs +139 -97
- package/Runtime/Core/Random/NativePcgRandom.cs.meta +11 -11
- package/Runtime/Core/Random/PRNG.cs +21 -7
- package/Runtime/Core/Random/PRNG.cs.meta +2 -2
- package/Runtime/Core/Random/PcgRandom.cs +243 -149
- package/Runtime/Core/Random/PcgRandom.cs.meta +11 -11
- package/Runtime/Core/Random/PerlinNoise.cs +369 -369
- package/Runtime/Core/Random/PerlinNoise.cs.meta +2 -2
- package/Runtime/Core/Random/RandomComparer.cs +34 -0
- package/Runtime/Core/Random/RandomComparer.cs.meta +3 -0
- package/Runtime/Core/Random/RandomState.cs +206 -131
- package/Runtime/Core/Random/RandomState.cs.meta +11 -11
- package/Runtime/Core/Random/RandomUtilities.cs +55 -26
- package/Runtime/Core/Random/RandomUtilities.cs.meta +11 -11
- package/Runtime/Core/Random/RomuDuo.cs +171 -116
- package/Runtime/Core/Random/RomuDuo.cs.meta +2 -2
- package/Runtime/Core/Random/SplitMix64.cs +134 -94
- package/Runtime/Core/Random/SplitMix64.cs.meta +2 -2
- package/Runtime/Core/Random/SquirrelRandom.cs +127 -84
- package/Runtime/Core/Random/SquirrelRandom.cs.meta +11 -11
- package/Runtime/Core/Random/SystemRandom.cs +203 -162
- package/Runtime/Core/Random/SystemRandom.cs.meta +11 -11
- package/Runtime/Core/Random/ThreadLocalRandom.cs +25 -12
- package/Runtime/Core/Random/ThreadLocalRandom.cs.meta +11 -11
- package/Runtime/Core/Random/UnityRandom.cs +109 -57
- package/Runtime/Core/Random/UnityRandom.cs.meta +11 -11
- package/Runtime/Core/Random/WyRandom.cs +158 -121
- package/Runtime/Core/Random/WyRandom.cs.meta +2 -2
- package/Runtime/Core/Random/XorShiftRandom.cs +106 -52
- package/Runtime/Core/Random/XorShiftRandom.cs.meta +11 -11
- package/Runtime/Core/Random/XoroShiroRandom.cs +184 -119
- package/Runtime/Core/Random/XoroShiroRandom.cs.meta +2 -2
- package/Runtime/Core/Random.meta +8 -8
- package/Runtime/Core/Serialization/JsonConverters/AnimationCurveConverter.cs +248 -0
- package/Runtime/Core/Serialization/JsonConverters/AnimationCurveConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/BitSetConverter.cs +119 -0
- package/Runtime/Core/Serialization/JsonConverters/BitSetConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/BoundingSphereConverter.cs +74 -0
- package/Runtime/Core/Serialization/JsonConverters/BoundingSphereConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/BoundsConverter.cs +132 -0
- package/Runtime/Core/Serialization/JsonConverters/BoundsConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/BoundsIntConverter.cs +135 -0
- package/Runtime/Core/Serialization/JsonConverters/BoundsIntConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/Color32Converter.cs +98 -0
- package/Runtime/Core/Serialization/JsonConverters/Color32Converter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/ColorBlockConverter.cs +123 -0
- package/Runtime/Core/Serialization/JsonConverters/ColorBlockConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/ColorConverter.cs +88 -88
- package/Runtime/Core/Serialization/JsonConverters/ColorConverter.cs.meta +2 -2
- package/Runtime/Core/Serialization/JsonConverters/CyclicBufferConverterFactory.cs +112 -0
- package/Runtime/Core/Serialization/JsonConverters/CyclicBufferConverterFactory.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/DequeConverterFactory.cs +62 -0
- package/Runtime/Core/Serialization/JsonConverters/DequeConverterFactory.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/FastVector2IntConverter.cs +72 -0
- package/Runtime/Core/Serialization/JsonConverters/FastVector2IntConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/FastVector3IntConverter.cs +80 -0
- package/Runtime/Core/Serialization/JsonConverters/FastVector3IntConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/GameObjectConverter.cs +36 -36
- package/Runtime/Core/Serialization/JsonConverters/GameObjectConverter.cs.meta +2 -2
- package/Runtime/Core/Serialization/JsonConverters/GradientConverter.cs +245 -0
- package/Runtime/Core/Serialization/JsonConverters/GradientConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/Hash128Converter.cs +92 -0
- package/Runtime/Core/Serialization/JsonConverters/Hash128Converter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/ImmutableBitSetConverter.cs +119 -0
- package/Runtime/Core/Serialization/JsonConverters/ImmutableBitSetConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/KVector2Converter.cs +72 -0
- package/Runtime/Core/Serialization/JsonConverters/KVector2Converter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/LayerMaskConverter.cs +95 -0
- package/Runtime/Core/Serialization/JsonConverters/LayerMaskConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/Matrix4x4Converter.cs +237 -218
- package/Runtime/Core/Serialization/JsonConverters/Matrix4x4Converter.cs.meta +2 -2
- package/Runtime/Core/Serialization/JsonConverters/MinMaxCurveConverter.cs +142 -0
- package/Runtime/Core/Serialization/JsonConverters/MinMaxCurveConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/MinMaxGradientConverter.cs +135 -0
- package/Runtime/Core/Serialization/JsonConverters/MinMaxGradientConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/PlaneConverter.cs +79 -0
- package/Runtime/Core/Serialization/JsonConverters/PlaneConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/PoseConverter.cs +76 -0
- package/Runtime/Core/Serialization/JsonConverters/PoseConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/QuaternionConverter.cs +88 -0
- package/Runtime/Core/Serialization/JsonConverters/QuaternionConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/RangeConverterFactory.cs +106 -0
- package/Runtime/Core/Serialization/JsonConverters/RangeConverterFactory.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/RangeIntConverter.cs +71 -0
- package/Runtime/Core/Serialization/JsonConverters/RangeIntConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/Ray2DConverter.cs +80 -0
- package/Runtime/Core/Serialization/JsonConverters/Ray2DConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/RayConverter.cs +76 -0
- package/Runtime/Core/Serialization/JsonConverters/RayConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/RaycastHitConverter.cs +115 -0
- package/Runtime/Core/Serialization/JsonConverters/RaycastHitConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/RectConverter.cs +84 -0
- package/Runtime/Core/Serialization/JsonConverters/RectConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/RectIntConverter.cs +88 -0
- package/Runtime/Core/Serialization/JsonConverters/RectIntConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/RectOffsetConverter.cs +87 -0
- package/Runtime/Core/Serialization/JsonConverters/RectOffsetConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/RenderTextureDescriptorConverter.cs +264 -0
- package/Runtime/Core/Serialization/JsonConverters/RenderTextureDescriptorConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/ResolutionConverter.cs +158 -0
- package/Runtime/Core/Serialization/JsonConverters/ResolutionConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/SceneConverter.cs +103 -0
- package/Runtime/Core/Serialization/JsonConverters/SceneConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/SphericalHarmonicsL2Converter.cs +121 -0
- package/Runtime/Core/Serialization/JsonConverters/SphericalHarmonicsL2Converter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/TouchConverter.cs +54 -0
- package/Runtime/Core/Serialization/JsonConverters/TouchConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/TypeConverter.cs +30 -28
- package/Runtime/Core/Serialization/JsonConverters/TypeConverter.cs.meta +2 -2
- package/Runtime/Core/Serialization/JsonConverters/Vector2Converter.cs +72 -74
- package/Runtime/Core/Serialization/JsonConverters/Vector2Converter.cs.meta +11 -11
- package/Runtime/Core/Serialization/JsonConverters/Vector2IntConverter.cs +72 -0
- package/Runtime/Core/Serialization/JsonConverters/Vector2IntConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/Vector3Converter.cs +80 -81
- package/Runtime/Core/Serialization/JsonConverters/Vector3Converter.cs.meta +11 -11
- package/Runtime/Core/Serialization/JsonConverters/Vector3IntConverter.cs +80 -0
- package/Runtime/Core/Serialization/JsonConverters/Vector3IntConverter.cs.meta +11 -0
- package/Runtime/Core/Serialization/JsonConverters/Vector4Converter.cs +88 -88
- package/Runtime/Core/Serialization/JsonConverters/Vector4Converter.cs.meta +2 -2
- package/Runtime/Core/Serialization/JsonConverters.meta +8 -8
- package/Runtime/Core/Serialization/ProtobufUnitySurrogates.cs +383 -0
- package/Runtime/Core/Serialization/ProtobufUnitySurrogates.cs.meta +11 -0
- package/Runtime/Core/Serialization/Serializer.cs +2020 -195
- package/Runtime/Core/Serialization/Serializer.cs.meta +11 -11
- package/Runtime/Core/Serialization.meta +8 -8
- package/Runtime/Core/Threading/SingleThreadedThreadPool.cs +228 -228
- package/Runtime/Core/Threading/SingleThreadedThreadPool.cs.meta +11 -11
- package/Runtime/Core/Threading.meta +8 -8
- package/Runtime/Core.meta +8 -8
- package/Runtime/Integrations/VContainer/ObjectResolverRelationalExtensions.cs +185 -0
- package/Runtime/Integrations/VContainer/ObjectResolverRelationalExtensions.cs.meta +11 -0
- package/Runtime/Integrations/VContainer/RelationalComponentEntryPoint.cs +109 -0
- package/Runtime/Integrations/VContainer/RelationalComponentEntryPoint.cs.meta +11 -0
- package/Runtime/Integrations/VContainer/RelationalComponentsBuilderExtensions.cs +78 -0
- package/Runtime/Integrations/VContainer/RelationalComponentsBuilderExtensions.cs.meta +11 -0
- package/Runtime/Integrations/VContainer/RelationalSceneAssignmentOptions.cs +83 -0
- package/Runtime/Integrations/VContainer/RelationalSceneAssignmentOptions.cs.meta +11 -0
- package/Runtime/Integrations/VContainer/WallstopStudios.UnityHelpers.Integration.VContainer.asmdef +30 -0
- package/Runtime/Integrations/VContainer/WallstopStudios.UnityHelpers.Integration.VContainer.asmdef.meta +7 -0
- package/Runtime/Integrations/VContainer.meta +8 -0
- package/Runtime/Integrations/Zenject/DiContainerRelationalExtensions.cs +180 -0
- package/Runtime/Integrations/Zenject/DiContainerRelationalExtensions.cs.meta +11 -0
- package/Runtime/Integrations/Zenject/RelationalComponentSceneInitializer.cs +105 -0
- package/Runtime/Integrations/Zenject/RelationalComponentSceneInitializer.cs.meta +11 -0
- package/Runtime/Integrations/Zenject/RelationalComponentsInstaller.cs +72 -0
- package/Runtime/Integrations/Zenject/RelationalComponentsInstaller.cs.meta +11 -0
- package/Runtime/Integrations/Zenject/RelationalSceneAssignmentOptions.cs +87 -0
- package/Runtime/Integrations/Zenject/RelationalSceneAssignmentOptions.cs.meta +11 -0
- package/Runtime/Integrations/Zenject/WallstopStudios.UnityHelpers.Integration.Zenject.asmdef +30 -0
- package/Runtime/Integrations/Zenject/WallstopStudios.UnityHelpers.Integration.Zenject.asmdef.meta +7 -0
- package/Runtime/Integrations/Zenject.meta +8 -0
- package/Runtime/Integrations.meta +8 -0
- package/Runtime/Protobuf-Net/System.Collections.Immutable.dll.meta +33 -33
- package/Runtime/Protobuf-Net/System.Runtime.CompilerServices.Unsafe.dll.meta +33 -33
- package/Runtime/Protobuf-Net/protobuf-net.Core.dll.meta +33 -33
- package/Runtime/Protobuf-Net/protobuf-net.dll.meta +33 -33
- package/Runtime/Protobuf-Net.meta +8 -8
- package/Runtime/Tags/AlwaysIncludeInAttributeMetadataCacheAttribute.cs +11 -0
- package/Runtime/Tags/AlwaysIncludeInAttributeMetadataCacheAttribute.cs.meta +11 -0
- package/Runtime/Tags/Attribute.cs +399 -205
- package/Runtime/Tags/Attribute.cs.meta +2 -2
- package/Runtime/Tags/AttributeEffect.cs +372 -281
- package/Runtime/Tags/AttributeEffect.cs.meta +2 -2
- package/Runtime/Tags/AttributeMetadataCache.cs +503 -0
- package/Runtime/Tags/AttributeMetadataCache.cs.meta +11 -0
- package/Runtime/Tags/AttributeMetadataFilters.cs +108 -0
- package/Runtime/Tags/AttributeMetadataFilters.cs.meta +11 -0
- package/Runtime/Tags/AttributeModification.cs +132 -48
- package/Runtime/Tags/AttributeModification.cs.meta +2 -2
- package/Runtime/Tags/AttributeUtilities.cs +376 -209
- package/Runtime/Tags/AttributeUtilities.cs.meta +2 -2
- package/Runtime/Tags/AttributesComponent.cs +237 -163
- package/Runtime/Tags/AttributesComponent.cs.meta +2 -2
- package/Runtime/Tags/CollisionSenses.cs +117 -91
- package/Runtime/Tags/CollisionSenses.cs.meta +2 -2
- package/Runtime/Tags/CosmeticEffectComponent.cs +112 -50
- package/Runtime/Tags/CosmeticEffectComponent.cs.meta +2 -2
- package/Runtime/Tags/CosmeticEffectData.cs +109 -63
- package/Runtime/Tags/CosmeticEffectData.cs.meta +2 -2
- package/Runtime/Tags/EffectHandle.cs +150 -65
- package/Runtime/Tags/EffectHandle.cs.meta +2 -2
- package/Runtime/Tags/EffectHandler.cs +470 -393
- package/Runtime/Tags/EffectHandler.cs.meta +2 -2
- package/Runtime/Tags/ModificationAction.cs +60 -9
- package/Runtime/Tags/ModificationAction.cs.meta +2 -2
- package/Runtime/Tags/ModifierDurationType.cs +71 -13
- package/Runtime/Tags/ModifierDurationType.cs.meta +2 -2
- package/Runtime/Tags/TagHandler.cs +373 -158
- package/Runtime/Tags/TagHandler.cs.meta +2 -2
- package/Runtime/Tags.meta +2 -2
- package/Runtime/Utils/AnimationEventEqualityComparer.cs +198 -161
- package/Runtime/Utils/AnimationEventEqualityComparer.cs.meta +11 -11
- package/Runtime/Utils/AnimatorEnumStateMachine.cs +110 -88
- package/Runtime/Utils/AnimatorEnumStateMachine.cs.meta +11 -11
- package/Runtime/Utils/Ascii85.cs +132 -115
- package/Runtime/Utils/Ascii85.cs.meta +2 -2
- package/Runtime/Utils/Buffers.cs +1151 -550
- package/Runtime/Utils/Buffers.cs.meta +11 -11
- package/Runtime/Utils/CenterPointOffset.cs +35 -30
- package/Runtime/Utils/CenterPointOffset.cs.meta +2 -2
- package/Runtime/Utils/ChildSpawner.cs +250 -157
- package/Runtime/Utils/ChildSpawner.cs.meta +2 -2
- package/Runtime/Utils/CircleLineRenderer.cs +142 -142
- package/Runtime/Utils/CircleLineRenderer.cs.meta +11 -11
- package/Runtime/Utils/CollisionProxy.cs +48 -48
- package/Runtime/Utils/CollisionProxy.cs.meta +2 -2
- package/Runtime/Utils/CoroutineHandler.cs +4 -4
- package/Runtime/Utils/CoroutineHandler.cs.meta +2 -2
- package/Runtime/Utils/DeferredDisposalResult.cs +20 -23
- package/Runtime/Utils/DeferredDisposalResult.cs.meta +2 -2
- package/Runtime/Utils/LZMA.cs +276 -53
- package/Runtime/Utils/LZMA.cs.meta +2 -2
- package/Runtime/Utils/MatchColliderToSprite.cs +104 -104
- package/Runtime/Utils/MatchColliderToSprite.cs.meta +2 -2
- package/Runtime/Utils/MatchTransform.cs +99 -82
- package/Runtime/Utils/MatchTransform.cs.meta +2 -2
- package/Runtime/Utils/Oscillator.cs +27 -27
- package/Runtime/Utils/Oscillator.cs.meta +11 -11
- package/Runtime/Utils/PolygonCollider2DOptimizer.cs +104 -83
- package/Runtime/Utils/PolygonCollider2DOptimizer.cs.meta +2 -2
- package/Runtime/Utils/RuntimeSingleton.cs +139 -88
- package/Runtime/Utils/RuntimeSingleton.cs.meta +11 -11
- package/Runtime/Utils/ScriptableObjectSingleton.cs +226 -85
- package/Runtime/Utils/ScriptableObjectSingleton.cs.meta +2 -2
- package/Runtime/Utils/SerializedStringComparer.cs +107 -107
- package/Runtime/Utils/SerializedStringComparer.cs.meta +2 -2
- package/Runtime/Utils/SetTextureImportData.cs +69 -69
- package/Runtime/Utils/SetTextureImportData.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Common/CRC.cs +70 -70
- package/Runtime/Utils/SevenZip/Common/CRC.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Common/InBuffer.cs +84 -84
- package/Runtime/Utils/SevenZip/Common/InBuffer.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Common/OutBuffer.cs +70 -70
- package/Runtime/Utils/SevenZip/Common/OutBuffer.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Common.meta +2 -2
- package/Runtime/Utils/SevenZip/Compress/LZ/IMatchFinder.cs +28 -28
- package/Runtime/Utils/SevenZip/Compress/LZ/IMatchFinder.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Compress/LZ/LzBinTree.cs +454 -454
- package/Runtime/Utils/SevenZip/Compress/LZ/LzBinTree.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Compress/LZ/LzInWindow.cs +179 -179
- package/Runtime/Utils/SevenZip/Compress/LZ/LzInWindow.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Compress/LZ/LzOutWindow.cs +137 -137
- package/Runtime/Utils/SevenZip/Compress/LZ/LzOutWindow.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Compress/LZ.meta +8 -8
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaBase.cs +110 -110
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaBase.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaDecoder.cs +525 -527
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaDecoder.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaEncoder.cs +1891 -1904
- package/Runtime/Utils/SevenZip/Compress/LZMA/LzmaEncoder.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Compress/LZMA.meta +8 -8
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoder.cs +242 -242
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoder.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBit.cs +146 -149
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBit.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs +177 -177
- package/Runtime/Utils/SevenZip/Compress/RangeCoder/RangeCoderBitTree.cs.meta +11 -11
- package/Runtime/Utils/SevenZip/Compress/RangeCoder.meta +8 -8
- package/Runtime/Utils/SevenZip/Compress.meta +8 -8
- package/Runtime/Utils/SevenZip/ICoder.cs +177 -177
- package/Runtime/Utils/SevenZip/ICoder.cs.meta +11 -11
- package/Runtime/Utils/SevenZip.meta +2 -2
- package/Runtime/Utils/SpriteRendererMetadata.cs +346 -370
- package/Runtime/Utils/SpriteRendererMetadata.cs.meta +2 -2
- package/Runtime/Utils/SpriteRendererSyncer.cs +100 -100
- package/Runtime/Utils/SpriteRendererSyncer.cs.meta +2 -2
- package/Runtime/Utils/StartTracker.cs +15 -15
- package/Runtime/Utils/StartTracker.cs.meta +2 -2
- package/Runtime/Utils/TextureScale.cs +356 -179
- package/Runtime/Utils/TextureScale.cs.meta +2 -2
- package/Runtime/Utils/TypeNameSorter.cs +17 -17
- package/Runtime/Utils/TypeNameSorter.cs.meta +2 -2
- package/Runtime/Utils/UnityObjectNameComparer.cs +89 -89
- package/Runtime/Utils/UnityObjectNameComparer.cs.meta +2 -2
- package/Runtime/Utils.meta +8 -8
- package/Runtime/Visuals/AnimatedSpriteLayer.cs +217 -130
- package/Runtime/Visuals/AnimatedSpriteLayer.cs.meta +2 -2
- package/Runtime/Visuals/UGUI/EnhancedImage.cs +218 -85
- package/Runtime/Visuals/UGUI/EnhancedImage.cs.meta +2 -2
- package/Runtime/Visuals/UGUI.meta +2 -2
- package/Runtime/Visuals/UIToolkit/LayeredImage.cs +781 -484
- package/Runtime/Visuals/UIToolkit/LayeredImage.cs.meta +2 -2
- package/Runtime/Visuals/UIToolkit/MultiFileSelectorElement.cs +945 -322
- package/Runtime/Visuals/UIToolkit/MultiFileSelectorElement.cs.meta +2 -2
- package/Runtime/Visuals/UIToolkit.meta +2 -2
- package/Runtime/Visuals.meta +2 -2
- package/Runtime/WallstopStudios.UnityHelpers.asmdef +22 -14
- package/Runtime/WallstopStudios.UnityHelpers.asmdef.meta +7 -7
- package/Runtime.meta +8 -8
- package/SERIALIZATION.md +648 -0
- package/SERIALIZATION.md.meta +7 -0
- package/SINGLETONS.md +427 -0
- package/SINGLETONS.md.meta +7 -0
- package/SPATIAL_TREES_2D_GUIDE.md +261 -0
- package/SPATIAL_TREES_2D_GUIDE.md.meta +7 -0
- package/SPATIAL_TREES_3D_GUIDE.md +214 -0
- package/SPATIAL_TREES_3D_GUIDE.md.meta +7 -0
- package/SPATIAL_TREE_2D_PERFORMANCE.md +238 -0
- package/SPATIAL_TREE_2D_PERFORMANCE.md.meta +7 -0
- package/SPATIAL_TREE_3D_PERFORMANCE.md +240 -0
- package/SPATIAL_TREE_3D_PERFORMANCE.md.meta +7 -0
- package/SPATIAL_TREE_SEMANTICS.md +106 -0
- package/SPATIAL_TREE_SEMANTICS.md.meta +7 -0
- package/Samples~/DI - VContainer/Prefabs/RelationalConsumer.prefab +77 -0
- package/Samples~/DI - VContainer/Prefabs/RelationalConsumer.prefab.meta +8 -0
- package/Samples~/DI - VContainer/Prefabs/Spawner.prefab +47 -0
- package/Samples~/DI - VContainer/Prefabs/Spawner.prefab.meta +8 -0
- package/Samples~/DI - VContainer/Prefabs.meta +9 -0
- package/Samples~/DI - VContainer/README.md +334 -0
- package/Samples~/DI - VContainer/README.md.meta +8 -0
- package/Samples~/DI - VContainer/Scenes/VContainer_Sample.unity +120 -0
- package/Samples~/DI - VContainer/Scenes/VContainer_Sample.unity.meta +8 -0
- package/Samples~/DI - VContainer/Scenes.meta +9 -0
- package/Samples~/DI - VContainer/Scripts/GameLifetimeScope.cs +24 -0
- package/Samples~/DI - VContainer/Scripts/GameLifetimeScope.cs.meta +12 -0
- package/Samples~/DI - VContainer/Scripts/RelationalConsumer.cs +21 -0
- package/Samples~/DI - VContainer/Scripts/RelationalConsumer.cs.meta +12 -0
- package/Samples~/DI - VContainer/Scripts/Samples.UnityHelpers.DI.VContainer.asmdef +37 -0
- package/Samples~/DI - VContainer/Scripts/Samples.UnityHelpers.DI.VContainer.asmdef.meta +8 -0
- package/Samples~/DI - VContainer/Scripts/Spawner.cs +21 -0
- package/Samples~/DI - VContainer/Scripts/Spawner.cs.meta +12 -0
- package/Samples~/DI - VContainer/Scripts.meta +9 -0
- package/Samples~/DI - VContainer.meta +9 -0
- package/Samples~/DI - Zenject/Prefabs/RelationalConsumer.prefab +77 -0
- package/Samples~/DI - Zenject/Prefabs/RelationalConsumer.prefab.meta +8 -0
- package/Samples~/DI - Zenject/Prefabs/SpawnerZenject.prefab +47 -0
- package/Samples~/DI - Zenject/Prefabs/SpawnerZenject.prefab.meta +8 -0
- package/Samples~/DI - Zenject/Prefabs.meta +9 -0
- package/Samples~/DI - Zenject/README.md +389 -0
- package/Samples~/DI - Zenject/README.md.meta +7 -0
- package/Samples~/DI - Zenject/Scenes/Zenject_Sample.unity +164 -0
- package/Samples~/DI - Zenject/Scenes/Zenject_Sample.unity.meta +8 -0
- package/Samples~/DI - Zenject/Scenes.meta +9 -0
- package/Samples~/DI - Zenject/Scripts/RelationalConsumer.cs +19 -0
- package/Samples~/DI - Zenject/Scripts/RelationalConsumer.cs.meta +12 -0
- package/Samples~/DI - Zenject/Scripts/Samples.UnityHelpers.DI.Zenject.asmdef +36 -0
- package/Samples~/DI - Zenject/Scripts/Samples.UnityHelpers.DI.Zenject.asmdef.meta +8 -0
- package/Samples~/DI - Zenject/Scripts/SceneContextPlaceholder.cs +47 -0
- package/Samples~/DI - Zenject/Scripts/SceneContextPlaceholder.cs.meta +12 -0
- package/Samples~/DI - Zenject/Scripts/SpawnerZenject.cs +20 -0
- package/Samples~/DI - Zenject/Scripts/SpawnerZenject.cs.meta +12 -0
- package/Samples~/DI - Zenject/Scripts.meta +9 -0
- package/Samples~/DI - Zenject.meta +9 -0
- package/Samples~/Random - PRNG/README.md +12 -0
- package/Samples~/Random - PRNG/README.md.meta +8 -0
- package/Samples~/Random - PRNG/Scripts/RandomPrngDemo.cs +28 -0
- package/Samples~/Random - PRNG/Scripts/RandomPrngDemo.cs.meta +12 -0
- package/Samples~/Random - PRNG/Scripts/Samples.UnityHelpers.Random.Prng.asmdef +17 -0
- package/Samples~/Random - PRNG/Scripts/Samples.UnityHelpers.Random.Prng.asmdef.meta +8 -0
- package/Samples~/Random - PRNG/Scripts.meta +9 -0
- package/Samples~/Random - PRNG.meta +9 -0
- package/Samples~/Relational Components - Basic/README.md +19 -0
- package/Samples~/Relational Components - Basic/README.md.meta +8 -0
- package/Samples~/Relational Components - Basic/Scripts/RelationalBasicConsumer.cs +37 -0
- package/Samples~/Relational Components - Basic/Scripts/RelationalBasicConsumer.cs.meta +12 -0
- package/Samples~/Relational Components - Basic/Scripts/Samples.UnityHelpers.Relational.Basic.asmdef +17 -0
- package/Samples~/Relational Components - Basic/Scripts/Samples.UnityHelpers.Relational.Basic.asmdef.meta +8 -0
- package/Samples~/Relational Components - Basic/Scripts.meta +9 -0
- package/Samples~/Relational Components - Basic.meta +9 -0
- package/Samples~/Serialization - JSON/README.md +13 -0
- package/Samples~/Serialization - JSON/README.md.meta +8 -0
- package/Samples~/Serialization - JSON/Scripts/JsonSerializationDemo.cs +50 -0
- package/Samples~/Serialization - JSON/Scripts/JsonSerializationDemo.cs.meta +12 -0
- package/Samples~/Serialization - JSON/Scripts/Samples.UnityHelpers.Serialization.Json.asmdef +17 -0
- package/Samples~/Serialization - JSON/Scripts/Samples.UnityHelpers.Serialization.Json.asmdef.meta +8 -0
- package/Samples~/Serialization - JSON/Scripts.meta +9 -0
- package/Samples~/Serialization - JSON.meta +9 -0
- package/Samples~/Spatial Structures - 2D and 3D/README.md +13 -0
- package/Samples~/Spatial Structures - 2D and 3D/README.md.meta +8 -0
- package/Samples~/Spatial Structures - 2D and 3D/Scripts/Samples.UnityHelpers.SpatialStructures.asmdef +17 -0
- package/Samples~/Spatial Structures - 2D and 3D/Scripts/Samples.UnityHelpers.SpatialStructures.asmdef.meta +8 -0
- package/Samples~/Spatial Structures - 2D and 3D/Scripts/SpatialStructuresDemo.cs +62 -0
- package/Samples~/Spatial Structures - 2D and 3D/Scripts/SpatialStructuresDemo.cs.meta +12 -0
- package/Samples~/Spatial Structures - 2D and 3D/Scripts.meta +9 -0
- package/Samples~/Spatial Structures - 2D and 3D.meta +9 -0
- package/Samples~/UGUI - EnhancedImage/README.md +12 -0
- package/Samples~/UGUI - EnhancedImage/README.md.meta +8 -0
- package/Samples~/UGUI - EnhancedImage/Scripts/EnhancedImageDemo.cs +36 -0
- package/Samples~/UGUI - EnhancedImage/Scripts/EnhancedImageDemo.cs.meta +12 -0
- package/Samples~/UGUI - EnhancedImage/Scripts/Samples.UnityHelpers.UGUI.EnhancedImage.asmdef +17 -0
- package/Samples~/UGUI - EnhancedImage/Scripts/Samples.UnityHelpers.UGUI.EnhancedImage.asmdef.meta +8 -0
- package/Samples~/UGUI - EnhancedImage/Scripts.meta +9 -0
- package/Samples~/UGUI - EnhancedImage.meta +9 -0
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/README.md +12 -0
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/README.md.meta +8 -0
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/Scripts/Editor/MultiFileSelectorSampleWindow.cs +45 -0
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/Scripts/Editor/MultiFileSelectorSampleWindow.cs.meta +12 -0
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/Scripts/Editor/Samples.UnityHelpers.UIToolkit.Editor.asmdef +19 -0
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/Scripts/Editor/Samples.UnityHelpers.UIToolkit.Editor.asmdef.meta +8 -0
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/Scripts/Editor.meta +9 -0
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/Scripts.meta +9 -0
- package/Samples~/UI Toolkit - MultiFile Selector (Editor).meta +9 -0
- package/Shaders/Materials/BackgroundMask-Material.mat +59 -59
- package/Shaders/Materials/BackgroundMask-Material.mat.meta +8 -8
- package/Shaders/Materials.meta +8 -8
- package/Shaders/ShaderGraph/BackgroundMask.shadergraph +1653 -1653
- package/Shaders/ShaderGraph/BackgroundMask.shadergraph.meta +10 -10
- package/Shaders/ShaderGraph/DebugDisplayValue.shadersubgraph +835 -835
- package/Shaders/ShaderGraph/DebugDisplayValue.shadersubgraph.meta +10 -10
- package/Shaders/ShaderGraph.meta +8 -8
- package/Shaders/Support/EnhancedImageSupport.shader +64 -0
- package/Shaders/Support/EnhancedImageSupport.shader.meta +9 -0
- package/Shaders/Support.meta +8 -0
- package/Shaders.meta +8 -8
- package/Styles/Elements/Progress/ArcedProgressBar.cs +345 -345
- package/Styles/Elements/Progress/ArcedProgressBar.cs.meta +2 -2
- package/Styles/Elements/Progress/CircularProgressBar.cs +307 -307
- package/Styles/Elements/Progress/CircularProgressBar.cs.meta +2 -2
- package/Styles/Elements/Progress/GlitchProgressBar.cs +416 -416
- package/Styles/Elements/Progress/GlitchProgressBar.cs.meta +2 -2
- package/Styles/Elements/Progress/LiquidProgressBar.cs +632 -632
- package/Styles/Elements/Progress/LiquidProgressBar.cs.meta +2 -2
- package/Styles/Elements/Progress/MarchingAntsProgressBar.cs +722 -722
- package/Styles/Elements/Progress/MarchingAntsProgressBar.cs.meta +2 -2
- package/Styles/Elements/Progress/RegularProgressBar.cs +405 -405
- package/Styles/Elements/Progress/RegularProgressBar.cs.meta +2 -2
- package/Styles/Elements/Progress/WigglyProgressBar.cs +837 -837
- package/Styles/Elements/Progress/WigglyProgressBar.cs.meta +2 -2
- package/Styles/Elements/Progress.meta +2 -2
- package/Styles/Elements.meta +2 -2
- package/Styles/USS/ArcedProgressBar.uss +18 -18
- package/Styles/USS/ArcedProgressBar.uss.meta +2 -2
- package/Styles/USS/CirclularProgressBar.uss +17 -17
- package/Styles/USS/CirclularProgressBar.uss.meta +2 -2
- package/Styles/USS/RegularProgressBar.uss +32 -32
- package/Styles/USS/RegularProgressBar.uss.meta +2 -2
- package/Styles/USS/WigglyProgressBar.uss +16 -16
- package/Styles/USS/WigglyProgressBar.uss.meta +2 -2
- package/Styles/USS.meta +2 -2
- package/Styles/WallstopStudios.UnityHelpers.Styles.asmdef +14 -17
- package/Styles/WallstopStudios.UnityHelpers.Styles.asmdef.meta +7 -7
- package/Styles.meta +2 -2
- package/THIRD_PARTY_NOTICES.md +74 -0
- package/THIRD_PARTY_NOTICES.md.meta +7 -0
- package/Tests/Editor/Attributes/AnimationEventHelpersTests.cs +155 -0
- package/Tests/Editor/Attributes/AnimationEventHelpersTests.cs.meta +11 -0
- package/Tests/Editor/Attributes.meta +8 -0
- package/Tests/Editor/Core/Attributes/RelationalComponentAssignerTests.cs +118 -0
- package/Tests/Editor/Core/Attributes/RelationalComponentAssignerTests.cs.meta +11 -0
- package/Tests/Editor/Core/Attributes.meta +8 -0
- package/Tests/Editor/Core.meta +8 -0
- package/Tests/Editor/Extensions/SerializedPropertyExtensionsTests.cs +194 -0
- package/Tests/Editor/Extensions/SerializedPropertyExtensionsTests.cs.meta +3 -0
- package/Tests/Editor/Extensions.meta +3 -0
- package/Tests/Editor/Helper/DummyScriptableObject.cs +6 -0
- package/Tests/Editor/Helper/DummyScriptableObject.cs.meta +3 -0
- package/Tests/Editor/Helper/HelpersTests.cs +101 -0
- package/Tests/Editor/Helper/HelpersTests.cs.meta +3 -0
- package/Tests/Editor/Helper/ObjectHelpersEditorTests.cs +63 -0
- package/Tests/Editor/Helper/ObjectHelpersEditorTests.cs.meta +11 -0
- package/Tests/Editor/Helper/PromptScope.cs +28 -0
- package/Tests/Editor/Helper/PromptScope.cs.meta +11 -0
- package/Tests/Editor/Helper/ReflectionHelpersEditorTests.cs +105 -0
- package/Tests/Editor/Helper/ReflectionHelpersEditorTests.cs.meta +11 -0
- package/Tests/Editor/Helper/SpriteHelpersTests.cs +334 -0
- package/Tests/Editor/Helper/SpriteHelpersTests.cs.meta +3 -0
- package/Tests/Editor/Helper/SpriteSettingsApplierAdditionalTests.cs +183 -0
- package/Tests/Editor/Helper/SpriteSettingsApplierAdditionalTests.cs.meta +11 -0
- package/Tests/Editor/Helper/SpriteSettingsApplierTests.cs +161 -0
- package/Tests/Editor/Helper/SpriteSettingsApplierTests.cs.meta +11 -0
- package/Tests/Editor/Helper.meta +3 -0
- package/Tests/Editor/Integrations/VContainer/VContainerIntegrationCompilationTests.cs +40 -0
- package/Tests/Editor/Integrations/VContainer/VContainerIntegrationCompilationTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalEntryPointTests.cs +77 -0
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalEntryPointTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/VContainer/WallstopStudios.UnityHelpers.Tests.Editor.VContainer.asmdef +36 -0
- package/Tests/Editor/Integrations/VContainer/WallstopStudios.UnityHelpers.Tests.Editor.VContainer.asmdef.meta +7 -0
- package/Tests/Editor/Integrations/VContainer.meta +8 -0
- package/Tests/Editor/Integrations/Zenject/WallstopStudios.UnityHelpers.Tests.Editor.Zenject.asmdef +36 -0
- package/Tests/Editor/Integrations/Zenject/WallstopStudios.UnityHelpers.Tests.Editor.Zenject.asmdef.meta +7 -0
- package/Tests/Editor/Integrations/Zenject/ZenjectIntegrationCompilationTests.cs +40 -0
- package/Tests/Editor/Integrations/Zenject/ZenjectIntegrationCompilationTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalInitializerTests.cs +76 -0
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalInitializerTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/Zenject.meta +8 -0
- package/Tests/Editor/Integrations.meta +8 -0
- package/Tests/Editor/MultiFileSelectorElementTests.cs +265 -0
- package/Tests/Editor/MultiFileSelectorElementTests.cs.meta +11 -0
- package/Tests/Editor/MultiFileSelectorPersistenceManagerTests.cs +100 -0
- package/Tests/Editor/MultiFileSelectorPersistenceManagerTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/AnimationCopierWindowTests.cs +199 -0
- package/Tests/Editor/Sprites/AnimationCopierWindowTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/ScriptableSpriteAtlasEditorTests.cs +108 -0
- package/Tests/Editor/Sprites/ScriptableSpriteAtlasEditorTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/SpriteCropperAdditionalTests.cs +323 -0
- package/Tests/Editor/Sprites/SpriteCropperAdditionalTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/SpriteCropperTests.cs +162 -0
- package/Tests/Editor/Sprites/SpriteCropperTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/SpritePivotAdjusterAdditionalTests.cs +227 -0
- package/Tests/Editor/Sprites/SpritePivotAdjusterAdditionalTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/SpritePivotAdjusterTests.cs +113 -0
- package/Tests/Editor/Sprites/SpritePivotAdjusterTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/TexturePlatformNameHelperTests.cs +28 -0
- package/Tests/Editor/Sprites/TexturePlatformNameHelperTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/TextureResizerWizardTests.cs +248 -0
- package/Tests/Editor/Sprites/TextureResizerWizardTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/TextureSettingsApplierAPITests.cs +180 -0
- package/Tests/Editor/Sprites/TextureSettingsApplierAPITests.cs.meta +11 -0
- package/Tests/Editor/Sprites/TextureSettingsApplierWizardAdditionalTests.cs +295 -0
- package/Tests/Editor/Sprites/TextureSettingsApplierWizardAdditionalTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/TextureSettingsApplierWizardTests.cs +134 -0
- package/Tests/Editor/Sprites/TextureSettingsApplierWizardTests.cs.meta +11 -0
- package/Tests/Editor/Sprites.meta +8 -0
- package/Tests/Editor/TestComponents/PrewarmTesterComponent.cs +10 -0
- package/Tests/Editor/TestComponents/PrewarmTesterComponent.cs.meta +11 -0
- package/Tests/Editor/TestComponents.meta +8 -0
- package/Tests/Editor/Tools/ImageBlurToolTests.cs +135 -0
- package/Tests/Editor/Tools/ImageBlurToolTests.cs.meta +11 -0
- package/Tests/Editor/Tools.meta +8 -0
- package/Tests/Editor/Utils/CommonTestBase.cs +208 -0
- package/Tests/Editor/Utils/CommonTestBase.cs.meta +11 -0
- package/Tests/Editor/Utils/ScriptableObjectSingletonCreatorEditorTests.cs +306 -0
- package/Tests/Editor/Utils/ScriptableObjectSingletonCreatorEditorTests.cs.meta +9 -0
- package/Tests/Editor/Utils/ScriptableObjectSingletonCreatorTests.cs +183 -0
- package/Tests/Editor/Utils/ScriptableObjectSingletonCreatorTests.cs.meta +11 -0
- package/Tests/Editor/Utils/ScriptableObjectSingletonTests.cs +466 -0
- package/Tests/Editor/Utils/ScriptableObjectSingletonTests.cs.meta +11 -0
- package/Tests/Editor/Utils.meta +3 -0
- package/Tests/Editor/WallstopStudios.UnityHelpers.Tests.Editor.asmdef +19 -0
- package/Tests/Editor/WallstopStudios.UnityHelpers.Tests.Editor.asmdef.meta +7 -0
- package/Tests/Editor/Windows/FitTextureSizeWindowTests.cs +781 -0
- package/Tests/Editor/Windows/FitTextureSizeWindowTests.cs.meta +11 -0
- package/Tests/Editor/Windows/PrefabCheckerFolderAdditionTests.cs +96 -0
- package/Tests/Editor/Windows/PrefabCheckerFolderAdditionTests.cs.meta +11 -0
- package/Tests/Editor/Windows/PrefabCheckerTests.cs +81 -0
- package/Tests/Editor/Windows/PrefabCheckerTests.cs.meta +11 -0
- package/Tests/Editor/Windows.meta +8 -0
- package/Tests/Editor.meta +8 -0
- package/Tests/Runtime/AssemblyInfo.cs +4 -0
- package/Tests/Runtime/AssemblyInfo.cs.meta +3 -0
- package/Tests/Runtime/Attributes/ChildComponentTests.cs +766 -81
- package/Tests/Runtime/Attributes/ChildComponentTests.cs.meta +2 -2
- package/Tests/Runtime/Attributes/Components/ExpectChildSpriteRenderers.cs +28 -28
- package/Tests/Runtime/Attributes/Components/ExpectChildSpriteRenderers.cs.meta +2 -2
- package/Tests/Runtime/Attributes/Components/ExpectParentSpriteRenderers.cs +28 -28
- package/Tests/Runtime/Attributes/Components/ExpectParentSpriteRenderers.cs.meta +2 -2
- package/Tests/Runtime/{Components → Attributes/Components}/RelationalComponentTesterComplex.cs +34 -34
- package/Tests/Runtime/{Components → Attributes/Components}/RelationalComponentTesterComplex.cs.meta +2 -2
- package/Tests/Runtime/Attributes/Components/RelationalComponentsTesterSimple.cs +37 -0
- package/Tests/Runtime/{Components → Attributes/Components}/RelationalComponentsTesterSimple.cs.meta +2 -2
- package/Tests/Runtime/Attributes/Components.meta +2 -2
- package/Tests/Runtime/Attributes/MiscRuntimeAttributeTests.cs +75 -0
- package/Tests/Runtime/Attributes/MiscRuntimeAttributeTests.cs.meta +11 -0
- package/Tests/Runtime/Attributes/NotNullAttributeTests.cs +26 -0
- package/Tests/Runtime/Attributes/NotNullAttributeTests.cs.meta +3 -0
- package/Tests/Runtime/Attributes/ParentComponentTests.cs +565 -68
- package/Tests/Runtime/Attributes/ParentComponentTests.cs.meta +2 -2
- package/Tests/Runtime/Attributes/RelationalComponentAdvancedTests.cs +614 -0
- package/Tests/Runtime/Attributes/RelationalComponentAdvancedTests.cs.meta +11 -0
- package/Tests/Runtime/Attributes/RelationalComponentBackwardCompatibilityTests.cs +478 -0
- package/Tests/Runtime/Attributes/RelationalComponentBackwardCompatibilityTests.cs.meta +11 -0
- package/Tests/Runtime/Attributes/RelationalComponentExtensionsTests.cs +56 -0
- package/Tests/Runtime/Attributes/RelationalComponentExtensionsTests.cs.meta +11 -0
- package/Tests/Runtime/Attributes/RelationalComponentHashSetTests.cs +226 -0
- package/Tests/Runtime/Attributes/RelationalComponentHashSetTests.cs.meta +11 -0
- package/Tests/Runtime/Attributes/RelationalComponentInitializerTests.cs +109 -0
- package/Tests/Runtime/Attributes/RelationalComponentInitializerTests.cs.meta +11 -0
- package/Tests/Runtime/Attributes/RelationalComponentTagAndNameFilterEdgeTests.cs +234 -0
- package/Tests/Runtime/Attributes/RelationalComponentTagAndNameFilterEdgeTests.cs.meta +11 -0
- package/Tests/Runtime/Attributes/SiblingComponentTests.cs +721 -0
- package/Tests/Runtime/Attributes/SiblingComponentTests.cs.meta +11 -0
- package/Tests/Runtime/Attributes/ValidateAssignmentAttributeTests.cs +96 -0
- package/Tests/Runtime/Attributes/ValidateAssignmentAttributeTests.cs.meta +11 -0
- package/Tests/Runtime/Attributes.meta +2 -2
- package/Tests/Runtime/Core/Random/RandomComparerTests.cs +166 -0
- package/Tests/Runtime/Core/Random/RandomComparerTests.cs.meta +11 -0
- package/Tests/Runtime/Core/Random.meta +8 -0
- package/Tests/Runtime/Core/Threading/SingleThreadedThreadPoolTests.cs +56 -56
- package/Tests/Runtime/Core/Threading/SingleThreadedThreadPoolTests.cs.meta +2 -2
- package/Tests/Runtime/Core/Threading.meta +2 -2
- package/Tests/Runtime/Core.meta +2 -2
- package/Tests/Runtime/DataStructures/BalancedKDTree2DTests.cs +562 -0
- package/Tests/Runtime/DataStructures/{BalancedKDTreeTests.cs.meta → BalancedKDTree2DTests.cs.meta} +11 -11
- package/Tests/Runtime/DataStructures/BalancedKDTree3DTests.cs +10 -0
- package/Tests/Runtime/DataStructures/BalancedKDTree3DTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/BitSetTests.cs +1400 -0
- package/Tests/Runtime/DataStructures/BitSetTests.cs.meta +3 -0
- package/Tests/Runtime/DataStructures/BoundingBox3DTests.cs +1215 -0
- package/Tests/Runtime/DataStructures/BoundingBox3DTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/CircleTests.cs +965 -0
- package/Tests/Runtime/DataStructures/CircleTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/CyclicBufferTests.cs +2083 -324
- package/Tests/Runtime/DataStructures/CyclicBufferTests.cs.meta +2 -2
- package/Tests/Runtime/DataStructures/DequeTests.cs +790 -0
- package/Tests/Runtime/DataStructures/DequeTests.cs.meta +3 -0
- package/Tests/Runtime/DataStructures/DisjointSetTests.cs +1114 -0
- package/Tests/Runtime/DataStructures/DisjointSetTests.cs.meta +3 -0
- package/Tests/Runtime/DataStructures/FastOneOfTests.cs +966 -0
- package/Tests/Runtime/DataStructures/FastOneOfTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/FastVector2IntTests.cs +286 -0
- package/Tests/Runtime/DataStructures/FastVector2IntTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/FastVector3IntTests.cs +414 -0
- package/Tests/Runtime/DataStructures/FastVector3IntTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/HeapTests.cs +1953 -0
- package/Tests/Runtime/DataStructures/HeapTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/ImmutableBitSetTests.cs +833 -0
- package/Tests/Runtime/DataStructures/ImmutableBitSetTests.cs.meta +3 -0
- package/Tests/Runtime/DataStructures/KDTree3DTestsBase.cs +297 -0
- package/Tests/Runtime/DataStructures/KDTree3DTestsBase.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/OctTree3DTests.cs +351 -0
- package/Tests/Runtime/DataStructures/OctTree3DTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/PriorityQueueTests.cs +71 -0
- package/Tests/Runtime/DataStructures/PriorityQueueTests.cs.meta +3 -0
- package/Tests/Runtime/DataStructures/ProtobufSerializationTests.cs +475 -0
- package/Tests/Runtime/DataStructures/ProtobufSerializationTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/QuadTree2DTests.cs +660 -0
- package/Tests/Runtime/DataStructures/QuadTree2DTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/RTree2DTests.cs +823 -0
- package/Tests/Runtime/DataStructures/RTree2DTests.cs.meta +3 -0
- package/Tests/Runtime/DataStructures/RTree3DTests.cs +270 -0
- package/Tests/Runtime/DataStructures/RTree3DTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SparseSetTests.cs +1146 -0
- package/Tests/Runtime/DataStructures/SparseSetTests.cs.meta +3 -0
- package/Tests/Runtime/DataStructures/SpatialHashTests.cs +992 -0
- package/Tests/Runtime/DataStructures/SpatialHashTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SpatialTree2DBoundsConsistencyTests.cs +351 -0
- package/Tests/Runtime/DataStructures/SpatialTree2DBoundsConsistencyTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SpatialTree2DBoundsEdgeTests.cs +127 -0
- package/Tests/Runtime/DataStructures/SpatialTree2DBoundsEdgeTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SpatialTree2DBoundsFuzzTests.cs +218 -0
- package/Tests/Runtime/DataStructures/SpatialTree2DBoundsFuzzTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SpatialTree2DTests.cs +396 -0
- package/Tests/Runtime/DataStructures/SpatialTree2DTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SpatialTree3DBoundsConsistencyTests.cs +281 -0
- package/Tests/Runtime/DataStructures/SpatialTree3DBoundsConsistencyTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SpatialTree3DBoundsEdgeTests.cs +127 -0
- package/Tests/Runtime/DataStructures/SpatialTree3DBoundsEdgeTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SpatialTree3DBoundsFuzzTests.cs +170 -0
- package/Tests/Runtime/DataStructures/SpatialTree3DBoundsFuzzTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SpatialTree3DTests.cs +474 -0
- package/Tests/Runtime/DataStructures/SpatialTree3DTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/SphereTests.cs +806 -0
- package/Tests/Runtime/DataStructures/SphereTests.cs.meta +3 -0
- package/Tests/Runtime/DataStructures/StringWrapperTests.cs +333 -0
- package/Tests/Runtime/DataStructures/StringWrapperTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/TimedCacheTests.cs +669 -0
- package/Tests/Runtime/DataStructures/TimedCacheTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/TrieTests.cs +3385 -0
- package/Tests/Runtime/DataStructures/TrieTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures/UnbalancedKDTree2DTests.cs +565 -0
- package/Tests/Runtime/DataStructures/{UnbalancedKDTreeTests.cs.meta → UnbalancedKDTree2DTests.cs.meta} +11 -11
- package/Tests/Runtime/DataStructures/UnbalancedKDTree3DTests.cs +10 -0
- package/Tests/Runtime/DataStructures/UnbalancedKDTree3DTests.cs.meta +11 -0
- package/Tests/Runtime/DataStructures.meta +8 -8
- package/Tests/Runtime/Extensions/AnimatorExtensionsTests.cs +28 -0
- package/Tests/Runtime/Extensions/AnimatorExtensionsTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/AsyncOperationExtensionsTests.cs +667 -0
- package/Tests/Runtime/Extensions/AsyncOperationExtensionsTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/CircleExtensionsTests.cs +230 -0
- package/Tests/Runtime/Extensions/CircleExtensionsTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/ColorExtensionsTests.cs +55 -0
- package/Tests/Runtime/Extensions/ColorExtensionsTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/DictionaryExtensionTests.cs +724 -438
- package/Tests/Runtime/Extensions/DictionaryExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions/DirectionExtensionsComprehensiveTests.cs +403 -0
- package/Tests/Runtime/Extensions/DirectionExtensionsComprehensiveTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/DirectionExtensionsTests.cs +69 -0
- package/Tests/Runtime/Extensions/DirectionExtensionsTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/EnumExtensionTests.cs +809 -153
- package/Tests/Runtime/Extensions/EnumExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions/IEnumerableExtensionsTests.cs +191 -0
- package/Tests/Runtime/Extensions/IEnumerableExtensionsTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/IListExtensionTests.cs +955 -169
- package/Tests/Runtime/Extensions/IListExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions/IReadonlyListExtensionTests.cs +266 -58
- package/Tests/Runtime/Extensions/IReadonlyListExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions/LoggingExtensionTests.cs +721 -718
- package/Tests/Runtime/Extensions/LoggingExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions/ProtoEqualityExtensionsTests.cs +565 -0
- package/Tests/Runtime/Extensions/ProtoEqualityExtensionsTests.cs.meta +3 -0
- package/Tests/Runtime/Extensions/ProtoEqualityPolymorphismTests.cs +100 -0
- package/Tests/Runtime/Extensions/ProtoEqualityPolymorphismTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs +719 -27
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions/StringExtensionTests.cs +2592 -31
- package/Tests/Runtime/Extensions/StringExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions/UnityExtensionsBasicTests.cs +166 -0
- package/Tests/Runtime/Extensions/UnityExtensionsBasicTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/UnityExtensionsComprehensiveTests.cs +1446 -0
- package/Tests/Runtime/Extensions/UnityExtensionsComprehensiveTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/UnityExtensionsMathTests.cs +1779 -0
- package/Tests/Runtime/Extensions/UnityExtensionsMathTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/UnityExtensionsVector2HullTests.cs +292 -0
- package/Tests/Runtime/Extensions/UnityExtensionsVector2HullTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions/UnityLogTagFormatterEdgeTests.cs +260 -0
- package/Tests/Runtime/Extensions/UnityLogTagFormatterEdgeTests.cs.meta +11 -0
- package/Tests/Runtime/Extensions.meta +2 -2
- package/Tests/Runtime/Helper/ArrayConverterTests.cs +19 -19
- package/Tests/Runtime/Helper/ArrayConverterTests.cs.meta +2 -2
- package/Tests/Runtime/Helper/AssignUtilitiesTests.cs +38 -0
- package/Tests/Runtime/Helper/AssignUtilitiesTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/DirectoryHelperTests.cs +347 -0
- package/Tests/Runtime/Helper/DirectoryHelperTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/EnumerablesTests.cs +45 -0
- package/Tests/Runtime/Helper/EnumerablesTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/FileHelperTests.cs +481 -0
- package/Tests/Runtime/Helper/FileHelperTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/FormattingHelpersTests.cs +353 -0
- package/Tests/Runtime/Helper/FormattingHelpersTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/FuncBasedComparerTests.cs +27 -0
- package/Tests/Runtime/Helper/FuncBasedComparerTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/GeometryTests.cs +517 -0
- package/Tests/Runtime/Helper/GeometryTests.cs.meta +3 -0
- package/Tests/Runtime/Helper/HelpersTests.cs +749 -0
- package/Tests/Runtime/Helper/HelpersTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/IterationHelpersTests.cs +173 -0
- package/Tests/Runtime/Helper/IterationHelpersTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/LineHelperTests.cs +662 -0
- package/Tests/Runtime/Helper/LineHelperTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/ObjectHelperTests.cs +444 -432
- package/Tests/Runtime/Helper/ObjectHelperTests.cs.meta +2 -2
- package/Tests/Runtime/Helper/ObjectsTests.cs +363 -0
- package/Tests/Runtime/Helper/ObjectsTests.cs.meta +3 -0
- package/Tests/Runtime/Helper/PathHelperTests.cs +183 -0
- package/Tests/Runtime/Helper/PathHelperTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/ReflectionHelperTests.cs +2199 -1493
- package/Tests/Runtime/Helper/ReflectionHelperTests.cs.meta +2 -2
- package/Tests/Runtime/Helper/ReflectionHelpersMemberLookupTests.cs +192 -0
- package/Tests/Runtime/Helper/ReflectionHelpersMemberLookupTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/ReflectionHelpersTypeScanningTests.cs +58 -0
- package/Tests/Runtime/Helper/ReflectionHelpersTypeScanningTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/SceneHelperTests.cs +77 -94
- package/Tests/Runtime/Helper/SceneHelperTests.cs.meta +2 -2
- package/Tests/Runtime/Helper/UnityMainThreadDispatcherTests.cs +45 -0
- package/Tests/Runtime/Helper/UnityMainThreadDispatcherTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/WallMathTests.cs +1884 -233
- package/Tests/Runtime/Helper/WallMathTests.cs.meta +2 -2
- package/Tests/Runtime/Helper.meta +2 -2
- package/Tests/Runtime/Integrations/VContainer/RelationalComponentsVContainerTests.cs +560 -0
- package/Tests/Runtime/Integrations/VContainer/RelationalComponentsVContainerTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/VContainer/WallstopStudios.UnityHelpers.Tests.Runtime.VContainer.asmdef +38 -0
- package/Tests/Runtime/Integrations/VContainer/WallstopStudios.UnityHelpers.Tests.Runtime.VContainer.asmdef.meta +7 -0
- package/Tests/Runtime/Integrations/VContainer.meta +8 -0
- package/Tests/Runtime/Integrations/Zenject/RelationalComponentsZenjectTests.cs +591 -0
- package/Tests/Runtime/Integrations/Zenject/RelationalComponentsZenjectTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/Zenject/WallstopStudios.UnityHelpers.Tests.Runtime.Zenject.asmdef +38 -0
- package/Tests/Runtime/Integrations/Zenject/WallstopStudios.UnityHelpers.Tests.Runtime.Zenject.asmdef.meta +7 -0
- package/Tests/Runtime/Integrations/Zenject.meta +8 -0
- package/Tests/Runtime/Integrations.meta +8 -0
- package/Tests/Runtime/Math/Line2DTests.cs +594 -0
- package/Tests/Runtime/Math/Line2DTests.cs.meta +11 -0
- package/Tests/Runtime/Math/Line3DTests.cs +655 -0
- package/Tests/Runtime/Math/Line3DTests.cs.meta +11 -0
- package/Tests/Runtime/Math/LineTests.cs +480 -0
- package/Tests/Runtime/Math/LineTests.cs.meta +11 -0
- package/Tests/Runtime/Math/ParabolaTests.cs +477 -0
- package/Tests/Runtime/Math/ParabolaTests.cs.meta +11 -0
- package/Tests/Runtime/Math/PointPolygonCheckTests.cs +939 -0
- package/Tests/Runtime/Math/PointPolygonCheckTests.cs.meta +11 -0
- package/Tests/Runtime/Math/RangeTests.cs +197 -0
- package/Tests/Runtime/Math/RangeTests.cs.meta +11 -0
- package/Tests/Runtime/Math.meta +8 -0
- package/Tests/Runtime/Performance/BenchmarkReadmeUpdater.cs +81 -0
- package/Tests/Runtime/Performance/BenchmarkReadmeUpdater.cs.meta +11 -0
- package/Tests/Runtime/Performance/JsonSerializationPerformanceTests.cs +421 -0
- package/Tests/Runtime/Performance/JsonSerializationPerformanceTests.cs.meta +3 -0
- package/Tests/Runtime/Performance/ListExtensionPerformanceTests.cs +76 -76
- package/Tests/Runtime/Performance/ListExtensionPerformanceTests.cs.meta +2 -2
- package/Tests/Runtime/Performance/ProtoEqualsPerformanceTests.cs +161 -0
- package/Tests/Runtime/Performance/ProtoEqualsPerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Performance/ProtoSerializationPerformanceTests.cs +207 -0
- package/Tests/Runtime/Performance/ProtoSerializationPerformanceTests.cs.meta +3 -0
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs +195 -181
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs.meta +11 -11
- package/Tests/Runtime/Performance/RelationComponentPerformanceTests.cs +60 -61
- package/Tests/Runtime/Performance/RelationComponentPerformanceTests.cs.meta +2 -2
- package/Tests/Runtime/Performance/SpatialTree2DPerformanceTests.cs +692 -0
- package/Tests/Runtime/Performance/SpatialTree2DPerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Performance/SpatialTree3DPerformanceTests.cs +650 -0
- package/Tests/Runtime/Performance/SpatialTree3DPerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Performance.meta +8 -8
- package/Tests/Runtime/Random/DotNetRandomTests.cs +9 -9
- package/Tests/Runtime/Random/DotNetRandomTests.cs.meta +2 -2
- package/Tests/Runtime/Random/IllusionFlowTests.cs +12 -12
- package/Tests/Runtime/Random/IllusionFlowTests.cs.meta +2 -2
- package/Tests/Runtime/Random/LinearCongruentialGeneratorTests.cs +12 -12
- package/Tests/Runtime/Random/LinearCongruentialGeneratorTests.cs.meta +2 -2
- package/Tests/Runtime/Random/PcgRandomTests.cs +9 -9
- package/Tests/Runtime/Random/PcgRandomTests.cs.meta +11 -11
- package/Tests/Runtime/Random/RandomProtoSerializationTests.cs +494 -0
- package/Tests/Runtime/Random/RandomProtoSerializationTests.cs.meta +3 -0
- package/Tests/Runtime/Random/RandomStateSerializationTests.cs +304 -0
- package/Tests/Runtime/Random/RandomStateSerializationTests.cs.meta +4 -0
- package/Tests/Runtime/Random/RandomTestBase.cs +836 -787
- package/Tests/Runtime/Random/RandomTestBase.cs.meta +11 -11
- package/Tests/Runtime/Random/RomuDuoRandomTests.cs +9 -9
- package/Tests/Runtime/Random/RomuDuoRandomTests.cs.meta +2 -2
- package/Tests/Runtime/Random/SplitMix64RandomTests.cs +9 -9
- package/Tests/Runtime/Random/SplitMix64RandomTests.cs.meta +2 -2
- package/Tests/Runtime/Random/SquirrelRandomTests.cs +14 -14
- package/Tests/Runtime/Random/SquirrelRandomTests.cs.meta +11 -11
- package/Tests/Runtime/Random/SystemRandomTests.cs +10 -10
- package/Tests/Runtime/Random/SystemRandomTests.cs.meta +11 -11
- package/Tests/Runtime/Random/UnityRandomTests.cs +9 -9
- package/Tests/Runtime/Random/UnityRandomTests.cs.meta +11 -11
- package/Tests/Runtime/Random/WyRandomTests.cs +9 -9
- package/Tests/Runtime/Random/WyRandomTests.cs.meta +2 -2
- package/Tests/Runtime/Random/XorShiftRandomTests.cs +9 -9
- package/Tests/Runtime/Random/XorShiftRandomTests.cs.meta +11 -11
- package/Tests/Runtime/Random/XoroShiroRandomTests.cs +9 -9
- package/Tests/Runtime/Random/XoroShiroRandomTests.cs.meta +2 -2
- package/Tests/Runtime/Random.meta +8 -8
- package/Tests/Runtime/RuntimeTestTimeouts.cs +3 -0
- package/Tests/Runtime/RuntimeTestTimeouts.cs.meta +11 -0
- package/Tests/Runtime/Scenes/Test1.unity +723 -723
- package/Tests/Runtime/Scenes/Test1.unity.meta +7 -7
- package/Tests/Runtime/Scenes/Test2.unity +723 -723
- package/Tests/Runtime/Scenes/Test2.unity.meta +7 -7
- package/Tests/Runtime/Scenes.meta +2 -2
- package/Tests/Runtime/Serialization/AdaptersJsonTests.cs +67 -0
- package/Tests/Runtime/Serialization/AdaptersJsonTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/BitSetJsonTests.cs +50 -0
- package/Tests/Runtime/Serialization/BitSetJsonTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/CyclicBufferJsonTests.cs +67 -0
- package/Tests/Runtime/Serialization/CyclicBufferJsonTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/DequeJsonTests.cs +70 -0
- package/Tests/Runtime/Serialization/DequeJsonTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/ImmutableBitSetJsonTests.cs +25 -0
- package/Tests/Runtime/Serialization/ImmutableBitSetJsonTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/JsonConverterTests.cs +1157 -0
- package/Tests/Runtime/Serialization/JsonConverterTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/JsonRoundtripComprehensiveTests.cs +239 -0
- package/Tests/Runtime/Serialization/JsonRoundtripComprehensiveTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/JsonSerializationCorrectnessTests.cs +458 -0
- package/Tests/Runtime/Serialization/JsonSerializationCorrectnessTests.cs.meta +3 -0
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs +156 -156
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs.meta +2 -2
- package/Tests/Runtime/Serialization/MathJsonTests.cs +79 -0
- package/Tests/Runtime/Serialization/MathJsonTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/ProtoInterfaceResolutionEdgeTests.cs +76 -0
- package/Tests/Runtime/Serialization/ProtoInterfaceResolutionEdgeTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/ProtoRootRegistrationTests.cs +80 -0
- package/Tests/Runtime/Serialization/ProtoRootRegistrationTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/ProtoRoundtripComprehensiveTests.cs +257 -0
- package/Tests/Runtime/Serialization/ProtoRoundtripComprehensiveTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/ProtoSerializationCorrectnessTests.cs +471 -0
- package/Tests/Runtime/Serialization/ProtoSerializationCorrectnessTests.cs.meta +3 -0
- package/Tests/Runtime/Serialization/ProtoSerializationTests.cs +169 -0
- package/Tests/Runtime/Serialization/ProtoSerializationTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/ProtoSerializeBehaviorTests.cs +62 -0
- package/Tests/Runtime/Serialization/ProtoSerializeBehaviorTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/SerializerAdditionalTests.cs +895 -0
- package/Tests/Runtime/Serialization/SerializerAdditionalTests.cs.meta +3 -0
- package/Tests/Runtime/Serialization/TypeConverterTests.cs +34 -0
- package/Tests/Runtime/Serialization/TypeConverterTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization.meta +2 -2
- package/Tests/Runtime/Tags/AttributeComponentTests.cs +174 -0
- package/Tests/Runtime/Tags/AttributeComponentTests.cs.meta +3 -0
- package/Tests/Runtime/Tags/AttributeDataTests.cs +312 -0
- package/Tests/Runtime/Tags/AttributeDataTests.cs.meta +11 -0
- package/Tests/Runtime/Tags/AttributeUtilitiesTests.cs +405 -0
- package/Tests/Runtime/Tags/AttributeUtilitiesTests.cs.meta +3 -0
- package/Tests/Runtime/Tags/CosmeticAndCollisionTests.cs +147 -0
- package/Tests/Runtime/Tags/CosmeticAndCollisionTests.cs.meta +11 -0
- package/Tests/Runtime/Tags/CosmeticEffectDataTests.cs +60 -0
- package/Tests/Runtime/Tags/CosmeticEffectDataTests.cs.meta +3 -0
- package/Tests/Runtime/Tags/EffectHandleTests.cs +61 -0
- package/Tests/Runtime/Tags/EffectHandleTests.cs.meta +3 -0
- package/Tests/Runtime/Tags/EffectHandlerTests.cs +270 -0
- package/Tests/Runtime/Tags/EffectHandlerTests.cs.meta +3 -0
- package/Tests/Runtime/Tags/Helpers/RecordingCosmeticComponent.cs +39 -0
- package/Tests/Runtime/Tags/Helpers/RecordingCosmeticComponent.cs.meta +3 -0
- package/Tests/Runtime/Tags/Helpers/TagTestBase.cs +49 -0
- package/Tests/Runtime/Tags/Helpers/TagTestBase.cs.meta +3 -0
- package/Tests/Runtime/Tags/Helpers/TestAttributesComponent.cs +28 -0
- package/Tests/Runtime/Tags/Helpers/TestAttributesComponent.cs.meta +3 -0
- package/Tests/Runtime/Tags/Helpers.meta +3 -0
- package/Tests/Runtime/Tags/TagHandlerTests.cs +108 -0
- package/Tests/Runtime/Tags/TagHandlerTests.cs.meta +3 -0
- package/Tests/Runtime/Tags.meta +8 -0
- package/Tests/Runtime/TestUtils/CommonTestBase.cs +213 -0
- package/Tests/Runtime/TestUtils/CommonTestBase.cs.meta +11 -0
- package/Tests/Runtime/TestUtils/GCAssert.cs +55 -0
- package/Tests/Runtime/TestUtils/GCAssert.cs.meta +11 -0
- package/Tests/Runtime/TestUtils/SpatialAssert.cs +33 -0
- package/Tests/Runtime/TestUtils/SpatialAssert.cs.meta +11 -0
- package/Tests/Runtime/TestUtils/SpatialDiagnostics.cs +195 -0
- package/Tests/Runtime/TestUtils/SpatialDiagnostics.cs.meta +11 -0
- package/Tests/Runtime/TestUtils.meta +8 -0
- package/Tests/Runtime/Utils/AnimationEventEqualityComparerTests.cs +144 -0
- package/Tests/Runtime/Utils/AnimationEventEqualityComparerTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/Ascii85Tests.cs +56 -0
- package/Tests/Runtime/Utils/Ascii85Tests.cs.meta +11 -0
- package/Tests/Runtime/Utils/BuffersTests.cs +1148 -741
- package/Tests/Runtime/Utils/BuffersTests.cs.meta +2 -2
- package/Tests/Runtime/Utils/BuffersWaitInstructionTests.cs +31 -0
- package/Tests/Runtime/Utils/BuffersWaitInstructionTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/CenterPointOffsetTests.cs +67 -0
- package/Tests/Runtime/Utils/CenterPointOffsetTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/ChildSpawnerTests.cs +490 -0
- package/Tests/Runtime/Utils/ChildSpawnerTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/CircleLineRendererTests.cs +80 -0
- package/Tests/Runtime/Utils/CircleLineRendererTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/CollisionProxyTests.cs +442 -0
- package/Tests/Runtime/Utils/CollisionProxyTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/CoroutineHandlerTests.cs +353 -0
- package/Tests/Runtime/Utils/CoroutineHandlerTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/DeferredDisposalResultTests.cs +44 -0
- package/Tests/Runtime/Utils/DeferredDisposalResultTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/LZMAComprehensiveTests.cs +249 -0
- package/Tests/Runtime/Utils/LZMAComprehensiveTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/LZMATests.cs +31 -0
- package/Tests/Runtime/Utils/LZMATests.cs.meta +11 -0
- package/Tests/Runtime/Utils/MatchColliderToSpriteAdditionalTests.cs +86 -0
- package/Tests/Runtime/Utils/MatchColliderToSpriteAdditionalTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/MatchColliderToSpriteTests.cs +503 -0
- package/Tests/Runtime/Utils/MatchColliderToSpriteTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/MatchTransformEdgeTests.cs +34 -0
- package/Tests/Runtime/Utils/MatchTransformEdgeTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/MatchTransformTests.cs +495 -0
- package/Tests/Runtime/Utils/MatchTransformTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/OscillatorTests.cs +540 -0
- package/Tests/Runtime/Utils/OscillatorTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/PolygonCollider2DOptimizerTests.cs +52 -0
- package/Tests/Runtime/Utils/PolygonCollider2DOptimizerTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/RuntimeSingletonTests.cs +766 -0
- package/Tests/Runtime/Utils/RuntimeSingletonTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/SerializedStringComparerEdgeTests.cs +47 -0
- package/Tests/Runtime/Utils/SerializedStringComparerEdgeTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/SerializedStringComparerTests.cs +361 -0
- package/Tests/Runtime/Utils/SerializedStringComparerTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/SpriteRendererMetadataTests.cs +383 -398
- package/Tests/Runtime/Utils/SpriteRendererMetadataTests.cs.meta +2 -2
- package/Tests/Runtime/Utils/SpriteRendererSyncTests.cs +134 -0
- package/Tests/Runtime/Utils/SpriteRendererSyncTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/StartTrackerTests.cs +24 -0
- package/Tests/Runtime/Utils/StartTrackerTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/TextureScaleEdgeTests.cs +114 -0
- package/Tests/Runtime/Utils/TextureScaleEdgeTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/TextureScaleTests.cs +298 -0
- package/Tests/Runtime/Utils/TextureScaleTests.cs.meta +3 -0
- package/Tests/Runtime/Utils/TypeNameSorterAdditionalTests.cs +36 -0
- package/Tests/Runtime/Utils/TypeNameSorterAdditionalTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/TypeNameSorterTests.cs +34 -0
- package/Tests/Runtime/Utils/TypeNameSorterTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/UnityObjectNameComparerEdgeTests.cs +63 -0
- package/Tests/Runtime/Utils/UnityObjectNameComparerEdgeTests.cs.meta +11 -0
- package/Tests/Runtime/Utils/UnityObjectNameComparerTests.cs +59 -0
- package/Tests/Runtime/Utils/UnityObjectNameComparerTests.cs.meta +11 -0
- package/Tests/Runtime/Utils.meta +2 -2
- package/Tests/Runtime/Visuals/AnimatedSpriteLayerTests.cs +266 -0
- package/Tests/Runtime/Visuals/AnimatedSpriteLayerTests.cs.meta +11 -0
- package/Tests/Runtime/Visuals/EnhancedImageTests.cs +184 -0
- package/Tests/Runtime/Visuals/EnhancedImageTests.cs.meta +11 -0
- package/Tests/Runtime/Visuals/LayeredImageTests.cs +422 -0
- package/Tests/Runtime/Visuals/LayeredImageTests.cs.meta +11 -0
- package/Tests/Runtime/Visuals/VisualsTestHelpers.cs +132 -0
- package/Tests/Runtime/Visuals/VisualsTestHelpers.cs.meta +11 -0
- package/Tests/Runtime/Visuals.meta +3 -0
- package/Tests/Runtime/WallstopStudios.UnityHelpers.Tests.Runtime.asmdef +24 -23
- package/Tests/Runtime/WallstopStudios.UnityHelpers.Tests.Runtime.asmdef.meta +7 -7
- package/Tests/Runtime.meta +8 -8
- package/Tests.meta +8 -8
- package/URP/VolumeProfiles/Post Processing Bloom Profile(URP).asset +63 -63
- package/URP/VolumeProfiles/Post Processing Bloom Profile(URP).asset.meta +8 -8
- package/URP/VolumeProfiles.meta +8 -8
- package/URP.meta +8 -8
- package/node_modules.meta +8 -0
- package/package.json +95 -38
- package/package.json.meta +7 -7
- package/scripts/check-eol.ps1 +52 -0
- package/scripts/check-eol.ps1.meta +7 -0
- package/scripts/clean-nul.ps1 +29 -0
- package/scripts/clean-nul.ps1.meta +7 -0
- package/scripts/lint-doc-links.ps1 +80 -0
- package/scripts/lint-doc-links.ps1.meta +7 -0
- package/scripts/normalize-eol.ps1 +71 -0
- package/scripts/normalize-eol.ps1.meta +7 -0
- package/scripts.meta +8 -0
- package/Editor/Sprites/ProjectAnimationSettings.cs +0 -50
- package/Editor/Sprites/ProjectAnimationSettings.cs.meta +0 -3
- package/Editor/Sprites/TextureSettingsApplier.cs +0 -178
- package/Editor/Sprites/TextureSettingsApplier.cs.meta +0 -3
- package/Runtime/Core/Attributes/ParentComponent.cs +0 -189
- package/Runtime/Core/DataStructure/KDTree.cs +0 -434
- package/Runtime/Core/DataStructure/QuadTree.cs +0 -431
- package/Runtime/Core/DataStructure/RTree.cs +0 -356
- package/Runtime/Core/Extension/HashSetExtensions.cs +0 -12
- package/Runtime/Core/Extension/HashSetExtensions.cs.meta +0 -11
- package/Runtime/Core/Math/Line.cs +0 -55
- package/Runtime/Core/Math/Line.cs.meta +0 -11
- package/Runtime/Core/Math/XXHash.cs +0 -310
- package/Runtime/Core/Math/XXHash.cs.meta +0 -11
- package/Tests/Runtime/Components/RelationalComponentsTesterSimple.cs +0 -40
- package/Tests/Runtime/Components.meta +0 -3
- package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs +0 -14
- package/Tests/Runtime/DataStructures/QuadTreeTests.cs +0 -14
- package/Tests/Runtime/DataStructures/QuadTreeTests.cs.meta +0 -11
- package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +0 -130
- package/Tests/Runtime/DataStructures/SpatialTreeTests.cs.meta +0 -11
- package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs +0 -14
- package/Tests/Runtime/Helper/FormattingHelperTests.cs +0 -129
- package/Tests/Runtime/Helper/FormattingHelperTests.cs.meta +0 -3
- package/Tests/Runtime/Performance/KDTreePerformanceTests.cs +0 -14
- package/Tests/Runtime/Performance/KDTreePerformanceTests.cs.meta +0 -11
- package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs +0 -14
- package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs.meta +0 -11
- package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +0 -158
- package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs.meta +0 -11
- package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs +0 -14
- package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs.meta +0 -11
- package/Third Party Notices.md +0 -1
package/README.md
CHANGED
|
@@ -1,188 +1,3195 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
](https://unity.com/releases/editor/whats-new/2021.3)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://github.com/wallstop/unity-helpers/actions/workflows/csharpier.yml)
|
|
6
|
+
[](https://github.com/wallstop/unity-helpers/actions/workflows/markdown-json.yml)
|
|
7
|
+
[](https://github.com/wallstop/unity-helpers/actions/workflows/lint-doc-links.yml)
|
|
8
|
+
[](https://github.com/wallstop/unity-helpers/actions/workflows/npm-publish.yml)
|
|
9
|
+
|
|
10
|
+
A comprehensive collection of high-performance utilities, data structures, and editor tools for Unity game development. Unity Helpers provides everything from blazing-fast random number generators and spatial trees to powerful editor wizards and component relationship management.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
**📚 New to Unity Helpers?** Start here: [Getting Started Guide](GETTING_STARTED.md)
|
|
15
|
+
|
|
16
|
+
**🔍 Looking for something specific?** Check the [Feature Index](INDEX.md)
|
|
17
|
+
|
|
18
|
+
**❓ Need a definition?** See the [Glossary](GLOSSARY.md)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 👋 First Time Here? Choose Your Path
|
|
23
|
+
|
|
24
|
+
Unity Helpers provides tools for different roles and needs. Pick your path to get started quickly:
|
|
25
|
+
|
|
26
|
+
### 🎮 For Gameplay Programmers
|
|
27
|
+
|
|
28
|
+
**You want:** Faster iteration on game features without sacrificing performance
|
|
29
|
+
|
|
30
|
+
<!-- markdownlint-disable MD036 -->
|
|
31
|
+
|
|
32
|
+
**Your quick wins:**
|
|
33
|
+
|
|
34
|
+
1. **[Random Number Generators](#random-number-generators)** - 10-15x faster with extensive API
|
|
35
|
+
- Weighted selection, Gaussian distributions, noise maps - all built-in
|
|
36
|
+
- Seedable for deterministic gameplay (replays, networking)
|
|
37
|
+
|
|
38
|
+
2. **[Relational Components](#auto-component-discovery)** - Stop writing GetComponent boilerplate
|
|
39
|
+
- `[SiblingComponent]`, `[ParentComponent]`, `[ChildComponent]` - that's it
|
|
40
|
+
- Works with DI containers (VContainer/Zenject)
|
|
41
|
+
|
|
42
|
+
3. **[Effects System](#effects-attributes-and-tags)** - Data-driven buffs/debuffs
|
|
43
|
+
- Designers create effects as ScriptableObjects
|
|
44
|
+
- Automatic stacking, timing, and tag management
|
|
45
|
+
|
|
46
|
+
**Start here:** [Random in 60 Seconds](#random-number-generation) → Try it now
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
### 🔧 For Tools & Editor Developers
|
|
51
|
+
|
|
52
|
+
**You want:** Automate asset pipelines and validation workflows
|
|
53
|
+
|
|
54
|
+
**Your quick wins:**
|
|
55
|
+
|
|
56
|
+
1. **[Editor Tools](#editor-tools)** - 20+ tools for sprites, animations, validation
|
|
57
|
+
- Sprite cropper, atlas generator, animation creator
|
|
58
|
+
- Prefab checker with comprehensive validation rules
|
|
59
|
+
|
|
60
|
+
2. **[ScriptableObject Singletons](#singleton-utilities-odin-compatible)** - Global settings management
|
|
61
|
+
- Auto-created from Resources/ folder
|
|
62
|
+
- ODIN Inspector compatible
|
|
63
|
+
|
|
64
|
+
3. **[Reflection Helpers](#reflectionhelpers-blazing-fast-reflection)** - 100x faster than System.Reflection
|
|
65
|
+
- IL-emitted delegates for field/property access
|
|
66
|
+
- Safe for IL2CPP and AOT platforms
|
|
67
|
+
|
|
68
|
+
**Start here:** [Editor Tools Guide](EDITOR_TOOLS_GUIDE.md)
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### ⚡ For Performance Engineers
|
|
73
|
+
|
|
74
|
+
**You want:** Optimize hotspots and eliminate GC pressure
|
|
75
|
+
|
|
76
|
+
**Your quick wins:**
|
|
77
|
+
|
|
78
|
+
1. **[Spatial Trees](#spatial-trees)** - O(log n) queries vs O(n) loops
|
|
79
|
+
- QuadTree2D, KDTree2D/3D, RTree2D/3D
|
|
80
|
+
- Scale to millions of objects
|
|
81
|
+
|
|
82
|
+
2. **[Buffering Pattern](#buffering-pattern)** - Zero-allocation queries
|
|
83
|
+
- Reusable collections eliminate GC spikes
|
|
84
|
+
- Professional-grade pooling with automatic cleanup
|
|
85
|
+
|
|
86
|
+
3. **[Data Structures](#data-structures)** - Production-ready containers
|
|
87
|
+
- Heaps, tries, sparse sets with clear trade-offs
|
|
88
|
+
- Performance benchmarks for informed decisions
|
|
89
|
+
|
|
90
|
+
**Start here:** [Spatial Trees 2D Guide](SPATIAL_TREES_2D_GUIDE.md) + [Performance Benchmarks](#performance)
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### 🏗️ For Architects & Tech Leads
|
|
95
|
+
|
|
96
|
+
**You want:** Understand integration points and architectural patterns
|
|
97
|
+
|
|
98
|
+
**Your quick wins:**
|
|
99
|
+
|
|
100
|
+
1. **[DI Integration](#dependency-injection-integrations)** - VContainer & Zenject support
|
|
101
|
+
- Automatic relational component wiring after DI injection
|
|
102
|
+
- Scene and runtime instantiation patterns
|
|
103
|
+
|
|
104
|
+
2. **[Serialization](#serialization)** - JSON/Protobuf with Unity type support
|
|
105
|
+
- Schema evolution for save files that never break
|
|
106
|
+
- Pooled buffers for hot paths
|
|
107
|
+
|
|
108
|
+
3. **[Feature Index](INDEX.md)** - Complete feature catalog
|
|
109
|
+
- Alphabetical reference with links
|
|
110
|
+
- Quick navigation to any feature
|
|
111
|
+
|
|
112
|
+
**Start here:** [DI Integration Samples](#dependency-injection-integrations) or [Architecture Overview](#why-unity-helpers)
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## ⚡ Top 5 Features That Will Save You Weeks
|
|
117
|
+
|
|
118
|
+
Unity Helpers isn't just about performance - it's about **eliminating entire categories of repetitive work**. Here are the five features that deliver the biggest time savings:
|
|
119
|
+
|
|
120
|
+
### 1. 🔌 Auto-Wire Components (Relational Components)
|
|
121
|
+
|
|
122
|
+
**Time saved: 10-20 minutes per script × 100+ scripts = 20+ hours**
|
|
123
|
+
|
|
124
|
+
Stop writing GetComponent boilerplate forever. Replace 20+ lines of repetitive code with 3 attributes.
|
|
125
|
+
|
|
126
|
+
```csharp
|
|
127
|
+
// ❌ OLD WAY: 20+ lines per script
|
|
128
|
+
void Awake() {
|
|
129
|
+
sprite = GetComponent<SpriteRenderer>();
|
|
130
|
+
if (sprite == null) Debug.LogError("Missing SpriteRenderer!");
|
|
131
|
+
|
|
132
|
+
rigidbody = GetComponentInParent<Rigidbody2D>();
|
|
133
|
+
if (rigidbody == null) Debug.LogError("Missing Rigidbody2D!");
|
|
134
|
+
|
|
135
|
+
colliders = GetComponentsInChildren<Collider2D>();
|
|
136
|
+
// 15 more lines...
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ✅ NEW WAY: 4 lines total
|
|
140
|
+
[SiblingComponent] private SpriteRenderer sprite;
|
|
141
|
+
[ParentComponent] private Rigidbody2D rigidbody;
|
|
142
|
+
[ChildComponent] private Collider2D[] colliders;
|
|
143
|
+
void Awake() => this.AssignRelationalComponents();
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Bonus:** Works with VContainer/Zenject for automatic DI + relational wiring!
|
|
147
|
+
|
|
148
|
+
[📖 Learn More](RELATIONAL_COMPONENTS.md) | [🎯 DI Integration](Samples~/DI%20-%20VContainer/README.md)
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### 2. 🎮 Data-Driven Effects System
|
|
153
|
+
|
|
154
|
+
**Time saved: 2-4 hours per effect × 50 effects = 150+ hours**
|
|
155
|
+
|
|
156
|
+
Designers create buffs/debuffs without touching code. Zero programmer time after initial setup.
|
|
157
|
+
|
|
158
|
+
```csharp
|
|
159
|
+
// Create once (ScriptableObject in editor):
|
|
160
|
+
// - HasteEffect: Speed × 1.5, duration 5s, tag "Haste", particle effect
|
|
161
|
+
|
|
162
|
+
// Use everywhere (zero boilerplate):
|
|
163
|
+
player.ApplyEffect(hasteEffect); // Apply buff
|
|
164
|
+
if (player.HasTag("Stunned")) return; // Query state
|
|
165
|
+
player.RemoveAllEffectsWithTag("Haste"); // Batch removal
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**What you get:**
|
|
169
|
+
|
|
170
|
+
- Automatic stacking & duration management
|
|
171
|
+
- Reference-counted tags for gameplay queries
|
|
172
|
+
- Cosmetic VFX/SFX that spawn/despawn automatically
|
|
173
|
+
- Designer-friendly iteration without code changes
|
|
174
|
+
|
|
175
|
+
[📖 Full Guide](EFFECTS_SYSTEM.md) | [🚀 5-Minute Tutorial](#effects-in-one-minute)
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### 3. 💾 Unity-Aware Serialization
|
|
180
|
+
|
|
181
|
+
**Time saved: 40+ hours on initial save system + preventing player data loss**
|
|
182
|
+
|
|
183
|
+
JSON/Protobuf that understands `Vector3`, `GameObject`, `Color` - no custom converters needed.
|
|
184
|
+
|
|
185
|
+
```csharp
|
|
186
|
+
// Vector3, Color, GameObject references just work:
|
|
187
|
+
var saveData = new SaveData {
|
|
188
|
+
playerPosition = new Vector3(1, 2, 3),
|
|
189
|
+
playerColor = Color.cyan,
|
|
190
|
+
inventory = new List<GameObject>()
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// One line to save:
|
|
194
|
+
byte[] data = Serializer.JsonSerialize(saveData);
|
|
195
|
+
|
|
196
|
+
// Schema evolution = never break old saves:
|
|
197
|
+
[ProtoMember(1)] public int gold;
|
|
198
|
+
[ProtoMember(2)] public Vector3 position;
|
|
199
|
+
// Adding new field? Old saves still load!
|
|
200
|
+
[ProtoMember(3)] public int level; // Safe to add
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Real-world impact:** Ship updates without worrying about corrupting player saves.
|
|
204
|
+
|
|
205
|
+
[📖 Serialization Guide](SERIALIZATION.md)
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### 4. 🎱 Professional Pooling (Buffers<T>)
|
|
210
|
+
|
|
211
|
+
**Time saved: Eliminates GC spikes = 5-10 FPS improvement in complex scenes**
|
|
212
|
+
|
|
213
|
+
Zero-allocation queries with automatic cleanup. Thread-safe, production-grade pooling in one line.
|
|
214
|
+
|
|
215
|
+
```csharp
|
|
216
|
+
// Get pooled buffer - automatically returned on scope exit
|
|
217
|
+
void ProcessEnemies(QuadTree2D<Enemy> enemyTree) {
|
|
218
|
+
using var lease = Buffers<Enemy>.List.Get(out List<Enemy> buffer);
|
|
219
|
+
|
|
220
|
+
// Use it for spatial query - zero allocations!
|
|
221
|
+
enemyTree.GetElementsInRange(playerPos, 10f, buffer);
|
|
222
|
+
|
|
223
|
+
foreach (Enemy enemy in buffer) {
|
|
224
|
+
enemy.TakeDamage(5f);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Buffer automatically returned to pool here - no cleanup needed
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Why this matters:**
|
|
232
|
+
|
|
233
|
+
- Stable 60 FPS under load (no GC spikes)
|
|
234
|
+
- AI systems querying hundreds of neighbors per frame
|
|
235
|
+
- Particle systems with thousands of particles
|
|
236
|
+
- Works for List, HashSet, Stack, Queue, and Arrays
|
|
237
|
+
|
|
238
|
+
[📖 Buffering Pattern](#buffering-pattern)
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
### 5. 🛠️ Editor Tools Suite
|
|
243
|
+
|
|
244
|
+
**Time saved: 1-2 hours per batch operation × weekly usage = hundreds of hours/year**
|
|
245
|
+
|
|
246
|
+
20+ tools that automate sprite cropping, animation creation, atlas generation, prefab validation.
|
|
247
|
+
|
|
248
|
+
**Common workflows:**
|
|
249
|
+
|
|
250
|
+
- **Sprite Cropper**: Add or remove transparent pixels from 500 sprites → 1 click (was: 30 minutes in Photoshop)
|
|
251
|
+
- **Animation Creator**: Bulk-create clips from naming patterns (`walk_0001.png`) → 1 minute (was: 20 minutes)
|
|
252
|
+
- **Prefab Checker**: Validate 200 prefabs for missing references → 1 click (was: manual QA)
|
|
253
|
+
- **Atlas Generator**: Create sprite atlases from regex/labels → automated (was: manual setup)
|
|
254
|
+
|
|
255
|
+
[📖 Editor Tools Guide](EDITOR_TOOLS_GUIDE.md)
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 💎 Hidden Gems Worth Discovering
|
|
260
|
+
|
|
261
|
+
These powerful utilities solve common problems but might not be obvious from feature names:
|
|
262
|
+
|
|
263
|
+
| Feature | What It Does | Time Saved |
|
|
264
|
+
| ----------------------------------------------------------------------------- | ----------------------------------------------------- | ------------------------------------ |
|
|
265
|
+
| **[Predictive Targeting](#predictive-targeting-hit-moving-targets)** | Perfect ballistics for turrets/missiles in one call | 2-3 hours per shooting system |
|
|
266
|
+
| **[UpdateShapeToSprite()](#lifecycle-helpers-no-more-destroyimmediate-bugs)** | Collider instantly matches sprite changes at runtime | 30 minutes per dynamic sprite system |
|
|
267
|
+
| **[Coroutine Jitter](#coroutine-timing-with-jitter)** | Prevents 100 enemies polling on same frame | Eliminates frame spikes |
|
|
268
|
+
| **[GetAngleWithSpeed()](#lifecycle-helpers-no-more-destroyimmediate-bugs)** | Smooth rotation toward target in one line | 15 minutes per rotating entity |
|
|
269
|
+
| **[IL-Emitted Reflection](#reflectionhelpers-blazing-fast-reflection)** | 100x faster than System.Reflection, IL2CPP safe | Critical for serialization/modding |
|
|
270
|
+
| **[SmartDestroy()](#lifecycle-helpers-no-more-destroyimmediate-bugs)** | Editor/runtime safe destruction (no scene corruption) | Prevents countless debugging hours |
|
|
271
|
+
| **[Convex/Concave Hulls](#convex--concave-hull-generation)** | Generate territory borders from point clouds | 4-6 hours per hull algorithm |
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## 🚀 Common Workflows: Get Started in Minutes
|
|
276
|
+
|
|
277
|
+
Jump straight to complete working examples for common scenarios:
|
|
278
|
+
|
|
279
|
+
### Save System in 5 Minutes
|
|
280
|
+
|
|
281
|
+
```csharp
|
|
282
|
+
using WallstopStudios.UnityHelpers.Core.Serialization;
|
|
283
|
+
|
|
284
|
+
// 1. Define your save data (Unity types just work)
|
|
285
|
+
[System.Serializable]
|
|
286
|
+
public class SaveData {
|
|
287
|
+
public Vector3 playerPosition;
|
|
288
|
+
public Quaternion playerRotation;
|
|
289
|
+
public Color playerColor;
|
|
290
|
+
public int gold;
|
|
291
|
+
public List<string> inventory;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// 2. Save to file (one line)
|
|
295
|
+
var data = new SaveData { /* ... */ };
|
|
296
|
+
Serializer.WriteToJsonFile(data, "save.json", pretty: true);
|
|
297
|
+
|
|
298
|
+
// 3. Load from file (one line)
|
|
299
|
+
SaveData loaded = Serializer.ReadFromJsonFile<SaveData>("save.json");
|
|
300
|
+
|
|
301
|
+
// ✅ Done! Vector3, Quaternion, Color all serialize correctly
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**What you get:** Schema evolution, Unity type support, human-readable files.
|
|
305
|
+
|
|
306
|
+
[📖 Full Serialization Guide](SERIALIZATION.md)
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
### Buff/Debuff System in 10 Minutes
|
|
311
|
+
|
|
312
|
+
```csharp
|
|
313
|
+
// 1. Create stats component
|
|
314
|
+
public class CharacterStats : AttributesComponent {
|
|
315
|
+
public Attribute Speed = 5f;
|
|
316
|
+
public Attribute Health = 100f;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// 2. Create effect in editor (ScriptableObject)
|
|
320
|
+
// - Right-click → Create → Wallstop Studios → Attribute Effect
|
|
321
|
+
// - Name: "HasteEffect"
|
|
322
|
+
// - Modification: Speed × 1.5
|
|
323
|
+
// - Duration: 5 seconds
|
|
324
|
+
// - Tags: "Haste"
|
|
325
|
+
|
|
326
|
+
// 3. Use it (zero boilerplate)
|
|
327
|
+
player.ApplyEffect(hasteEffect); // Apply
|
|
328
|
+
if (player.HasTag("Stunned")) return; // Query
|
|
329
|
+
player.RemoveAllEffectsWithTag("Haste"); // Remove
|
|
330
|
+
|
|
331
|
+
// ✅ Done! Designers can now create hundreds of effects without code
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**What you get:** Automatic stacking, duration management, cosmetic VFX/SFX, tags.
|
|
335
|
+
|
|
336
|
+
[📖 5-Minute Tutorial](EFFECTS_SYSTEM_TUTORIAL.md) | [📖 Full Guide](EFFECTS_SYSTEM.md)
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
### DI-Integrated Component Auto-Wiring in 2 Minutes
|
|
341
|
+
|
|
342
|
+
**With VContainer:**
|
|
343
|
+
|
|
344
|
+
```csharp
|
|
345
|
+
// 1. Register in LifetimeScope
|
|
346
|
+
using WallstopStudios.UnityHelpers.Integrations.VContainer;
|
|
347
|
+
|
|
348
|
+
protected override void Configure(IContainerBuilder builder) {
|
|
349
|
+
builder.RegisterRelationalComponents();
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// 2. Use it (DI + relational fields both auto-wired)
|
|
353
|
+
public class Player : MonoBehaviour {
|
|
354
|
+
[Inject] private IInputService _input; // DI injected
|
|
355
|
+
[SiblingComponent] private Animator _animator; // Auto-wired
|
|
356
|
+
// No Awake() needed!
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// ✅ Done! Both DI dependencies and hierarchy references wired automatically
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**With Zenject:**
|
|
363
|
+
|
|
364
|
+
```csharp
|
|
365
|
+
// 1. Add RelationalComponentsInstaller to SceneContext (toggle scene scan)
|
|
366
|
+
|
|
367
|
+
// 2. Use it
|
|
368
|
+
public class Player : MonoBehaviour {
|
|
369
|
+
[Inject] private IInputService _input; // DI injected
|
|
370
|
+
[SiblingComponent] private Animator _animator; // Auto-wired
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// ✅ Done! Scene objects wired on initialize, runtime via InstantiateComponentWithRelations()
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
**What you get:** Zero boilerplate, works with scene + runtime objects, graceful fallback.
|
|
377
|
+
|
|
378
|
+
[📖 VContainer Guide](Samples~/DI%20-%20VContainer/README.md) | [📖 Zenject Guide](Samples~/DI%20-%20Zenject/README.md)
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
### Fast Spatial Queries in 3 Minutes
|
|
383
|
+
|
|
384
|
+
```csharp
|
|
385
|
+
using WallstopStudios.UnityHelpers.Core.DataStructure;
|
|
386
|
+
|
|
387
|
+
// 1. Build tree (once or per frame for moving objects)
|
|
388
|
+
Enemy[] enemies = FindObjectsOfType<Enemy>();
|
|
389
|
+
var tree = new QuadTree2D<Enemy>(enemies, e => e.transform.position);
|
|
390
|
+
|
|
391
|
+
// 2. Query efficiently (O(log n) vs O(n))
|
|
392
|
+
using var lease = Buffers<Enemy>.List.Get(out List<Enemy> nearby);
|
|
393
|
+
tree.GetElementsInRange(playerPos, radius: 10f, nearby);
|
|
394
|
+
|
|
395
|
+
// 3. Process results (zero GC with pooled buffer)
|
|
396
|
+
foreach (Enemy enemy in nearby) {
|
|
397
|
+
enemy.TakeDamage(5f);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// ✅ Done! Scales to millions of objects, automatic buffer pooling
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**What you get:** 100-1000x faster queries, zero GC, production-ready.
|
|
404
|
+
|
|
405
|
+
[📖 2D Trees Guide](SPATIAL_TREES_2D_GUIDE.md) | [📊 Performance](SPATIAL_TREE_2D_PERFORMANCE.md)
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## 📊 With vs Without Unity Helpers
|
|
410
|
+
|
|
411
|
+
Real code comparisons showing exactly what you're avoiding:
|
|
412
|
+
|
|
413
|
+
### Component Wiring: 20 Lines → 4 Lines
|
|
414
|
+
|
|
415
|
+
| Without Unity Helpers | With Unity Helpers |
|
|
416
|
+
| ---------------------------------- | ----------------------------- |
|
|
417
|
+
| **25 lines per script** | **4 lines total** |
|
|
418
|
+
| Manual GetComponent calls | Attributes |
|
|
419
|
+
| Manual null checks | Auto-validated |
|
|
420
|
+
| Error-prone | Self-documenting |
|
|
421
|
+
| Must update when hierarchy changes | Handles changes automatically |
|
|
422
|
+
|
|
423
|
+
```csharp
|
|
424
|
+
// ❌ WITHOUT (25 lines)
|
|
425
|
+
public class Player : MonoBehaviour {
|
|
426
|
+
private SpriteRenderer sprite;
|
|
427
|
+
private Animator animator;
|
|
428
|
+
private Rigidbody2D rb;
|
|
429
|
+
private Collider2D[] colliders;
|
|
430
|
+
|
|
431
|
+
void Awake() {
|
|
432
|
+
sprite = GetComponent<SpriteRenderer>();
|
|
433
|
+
if (sprite == null) {
|
|
434
|
+
Debug.LogError($"Missing SpriteRenderer on {name}!");
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
animator = GetComponent<Animator>();
|
|
438
|
+
if (animator == null) {
|
|
439
|
+
Debug.LogError($"Missing Animator on {name}!");
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
rb = GetComponentInParent<Rigidbody2D>();
|
|
443
|
+
if (rb == null) {
|
|
444
|
+
Debug.LogError($"Missing Rigidbody2D in parent of {name}!");
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
colliders = GetComponentsInChildren<Collider2D>();
|
|
448
|
+
if (colliders.Length == 0) {
|
|
449
|
+
Debug.LogWarning($"No Collider2D found in children of {name}!");
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// ✅ WITH (4 lines)
|
|
455
|
+
public class Player : MonoBehaviour {
|
|
456
|
+
[SiblingComponent] private SpriteRenderer sprite;
|
|
457
|
+
[SiblingComponent] private Animator animator;
|
|
458
|
+
[ParentComponent] private Rigidbody2D rb;
|
|
459
|
+
[ChildComponent] private Collider2D[] colliders;
|
|
460
|
+
|
|
461
|
+
void Awake() => this.AssignRelationalComponents();
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
**Impact:** 10-20 minutes saved per script × 100 scripts = **16-33 hours saved**
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
### Buff/Debuff System: 80 Lines → 0 Lines
|
|
470
|
+
|
|
471
|
+
| Without Unity Helpers | With Unity Helpers |
|
|
472
|
+
| ---------------------------- | -------------------------- |
|
|
473
|
+
| **80-100 lines per effect** | **0 lines - editor only** |
|
|
474
|
+
| Manual duration tracking | Automatic |
|
|
475
|
+
| Manual stacking logic | Built-in |
|
|
476
|
+
| Manual VFX lifecycle | Cosmetic system |
|
|
477
|
+
| Code changes for new effects | Designer creates in editor |
|
|
478
|
+
|
|
479
|
+
```csharp
|
|
480
|
+
// ❌ WITHOUT (80-100 lines per effect type)
|
|
481
|
+
public class HasteEffect : MonoBehaviour {
|
|
482
|
+
public float speedMultiplier = 1.5f;
|
|
483
|
+
public float duration = 5f;
|
|
484
|
+
public GameObject particlePrefab;
|
|
485
|
+
|
|
486
|
+
private float remainingTime;
|
|
487
|
+
private float originalSpeed;
|
|
488
|
+
private GameObject spawnedParticles;
|
|
489
|
+
private PlayerStats stats;
|
|
490
|
+
|
|
491
|
+
void Start() {
|
|
492
|
+
stats = GetComponent<PlayerStats>();
|
|
493
|
+
originalSpeed = stats.speed;
|
|
494
|
+
stats.speed *= speedMultiplier;
|
|
495
|
+
remainingTime = duration;
|
|
496
|
+
|
|
497
|
+
if (particlePrefab != null) {
|
|
498
|
+
spawnedParticles = Instantiate(particlePrefab, transform);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
void Update() {
|
|
503
|
+
remainingTime -= Time.deltaTime;
|
|
504
|
+
if (remainingTime <= 0) {
|
|
505
|
+
RemoveEffect();
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
void RemoveEffect() {
|
|
510
|
+
if (stats != null) {
|
|
511
|
+
stats.speed = originalSpeed;
|
|
512
|
+
}
|
|
513
|
+
if (spawnedParticles != null) {
|
|
514
|
+
Destroy(spawnedParticles);
|
|
515
|
+
}
|
|
516
|
+
Destroy(this);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
void OnDestroy() {
|
|
520
|
+
if (stats != null && stats.speed != originalSpeed) {
|
|
521
|
+
stats.speed = originalSpeed;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// TODO: Handle stacking (another 30 lines)
|
|
526
|
+
// TODO: Handle reapplication (another 20 lines)
|
|
527
|
+
// TODO: Handle early removal (another 10 lines)
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// ✅ WITH (0 lines - create in editor)
|
|
531
|
+
// Right-click → Create → Wallstop Studios → Attribute Effect
|
|
532
|
+
// Fill in fields in Inspector:
|
|
533
|
+
// - Modification: Speed × 1.5
|
|
534
|
+
// - Duration: 5 seconds
|
|
535
|
+
// - Cosmetic: particle prefab
|
|
536
|
+
// - Tags: "Haste"
|
|
537
|
+
//
|
|
538
|
+
// Use: player.ApplyEffect(hasteEffect);
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
**Impact:** 2-4 hours per effect type × 50 effects = **100-200 hours saved**
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
### Spatial Queries: O(n) → O(log n)
|
|
546
|
+
|
|
547
|
+
| Without Unity Helpers | With Unity Helpers |
|
|
548
|
+
| ---------------------------------------------- | ----------------------------------------- |
|
|
549
|
+
| **O(n) linear search** | **O(log n) tree query** |
|
|
550
|
+
| Scales poorly (10,000 objects = 10,000 checks) | Scales well (10,000 objects = ~13 checks) |
|
|
551
|
+
| Allocates garbage | Zero GC with pooling |
|
|
552
|
+
|
|
553
|
+
```csharp
|
|
554
|
+
// ❌ WITHOUT (slow, allocates)
|
|
555
|
+
Enemy[] enemies = FindObjectsOfType<Enemy>(); // O(n) + allocation
|
|
556
|
+
List<Enemy> nearby = new List<Enemy>(); // Allocation
|
|
557
|
+
|
|
558
|
+
foreach (Enemy enemy in enemies) { // O(n) iteration
|
|
559
|
+
float dist = Vector2.Distance(playerPos, enemy.transform.position);
|
|
560
|
+
if (dist <= radius) {
|
|
561
|
+
nearby.Add(enemy);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
// Result: 10,000 enemies = 10,000 distance checks per frame
|
|
565
|
+
// GC pressure from new List every frame
|
|
566
|
+
|
|
567
|
+
// ✅ WITH (fast, zero GC)
|
|
568
|
+
var tree = new QuadTree2D<Enemy>(enemies, e => e.transform.position);
|
|
569
|
+
|
|
570
|
+
using var lease = Buffers<Enemy>.List.Get(out List<Enemy> nearby);
|
|
571
|
+
tree.GetElementsInRange(playerPos, radius, nearby);
|
|
572
|
+
// Result: 10,000 enemies = ~13 tree node checks
|
|
573
|
+
// Zero GC with pooled buffer reuse
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
**Performance gain:** 100-1000x faster queries, stable 60 FPS with thousands of objects
|
|
577
|
+
|
|
578
|
+
[📊 See Benchmarks](SPATIAL_TREE_2D_PERFORMANCE.md)
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
582
|
+
### Save System: 40 Hours → 5 Minutes
|
|
583
|
+
|
|
584
|
+
| Without Unity Helpers | With Unity Helpers |
|
|
585
|
+
| --------------------------------------- | ------------------ |
|
|
586
|
+
| **40+ hours initial** | **5 minutes** |
|
|
587
|
+
| Write custom converters for Unity types | Built-in |
|
|
588
|
+
| Handle schema changes manually | Automatic |
|
|
589
|
+
| Risk breaking old saves | Schema evolution |
|
|
590
|
+
|
|
591
|
+
```csharp
|
|
592
|
+
// ❌ WITHOUT (need custom converters for every Unity type)
|
|
593
|
+
public class Vector3Converter : JsonConverter<Vector3> {
|
|
594
|
+
public override Vector3 Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options) {
|
|
595
|
+
// 20 lines of parsing logic...
|
|
596
|
+
}
|
|
597
|
+
public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options) {
|
|
598
|
+
// 15 lines of writing logic...
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
// Repeat for: Vector2, Color, Quaternion, Matrix4x4, GameObject references...
|
|
602
|
+
// Then configure options, handle file I/O, catch exceptions...
|
|
603
|
+
|
|
604
|
+
// ✅ WITH (Unity types work out of the box)
|
|
605
|
+
var data = new SaveData {
|
|
606
|
+
position = new Vector3(1, 2, 3), // Works
|
|
607
|
+
color = Color.cyan, // Works
|
|
608
|
+
rotation = Quaternion.identity // Works
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
Serializer.WriteToJsonFile(data, "save.json", pretty: true);
|
|
612
|
+
SaveData loaded = Serializer.ReadFromJsonFile<SaveData>("save.json");
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
**Impact:** 40+ hours initial development + preventing player data corruption on updates
|
|
616
|
+
|
|
617
|
+
---
|
|
618
|
+
|
|
619
|
+
## Quick Onramp
|
|
620
|
+
|
|
621
|
+
### Why Unity Helpers? The Killer Features
|
|
622
|
+
|
|
623
|
+
**⚡ Performance - Make Your Game Faster**
|
|
624
|
+
|
|
625
|
+
- **10-15x faster random** ([PRNG.Instance](RANDOM_PERFORMANCE.md)) vs UnityEngine.Random + seedable for determinism
|
|
626
|
+
- **Zero-allocation spatial queries** ([Buffering Pattern](#buffering-pattern)) → no GC spikes, stable 60fps
|
|
627
|
+
- **O(log n) spatial trees** ([Spatial Trees](SPATIAL_TREES_2D_GUIDE.md)) scale to millions of objects
|
|
628
|
+
- **IL-emitted reflection** ([ReflectionHelpers](#reflectionhelpers-blazing-fast-reflection)) → field/property access 10-100x faster than System.Reflection
|
|
629
|
+
|
|
630
|
+
**🚀 Productivity - Ship Features Faster**
|
|
631
|
+
|
|
632
|
+
- **Auto-wire components** ([Relational Components](RELATIONAL_COMPONENTS.md)) → eliminate GetComponent boilerplate
|
|
633
|
+
- **Data-driven effects** ([Effects System](EFFECTS_SYSTEM.md)) → designers create 100s of buffs/debuffs without programmer
|
|
634
|
+
- **20+ editor tools** ([Editor Tools](EDITOR_TOOLS_GUIDE.md)) → automate sprite cropping, animations, atlases
|
|
635
|
+
- **Predictive targeting** ([PredictCurrentTarget](#predictive-targeting-hit-moving-targets)) → perfect ballistics for turrets/missiles in 1 line
|
|
636
|
+
- **Professional pooling** ([Buffers](#professional-grade-object-pooling)) → zero-alloc patterns with automatic cleanup
|
|
637
|
+
|
|
638
|
+
**🛡️ Production-Ready - Never Break Player Saves**
|
|
639
|
+
|
|
640
|
+
- **Protobuf schema evolution** ([Serialization](SERIALIZATION.md#protobuf-schema-evolution-the-killer-feature)) → add/remove fields without breaking old saves
|
|
641
|
+
- **4,000+ test cases** → used in shipped commercial games
|
|
642
|
+
- **Fully multiplatform** → WebGL, IL2CPP, Mobile, Desktop, Consoles with SINGLE_THREADED hot path optimizations
|
|
643
|
+
- **IL2CPP optimized** → works with Unity's aggressive compiler, full AOT compatibility
|
|
644
|
+
- **SmartDestroy** ([Lifecycle Helpers](#lifecycle-helpers-no-more-destroyimmediate-bugs)) → editor/runtime safe destruction, never corrupt scenes again
|
|
645
|
+
|
|
646
|
+
---
|
|
647
|
+
|
|
648
|
+
TL;DR — Why use this?
|
|
649
|
+
|
|
650
|
+
- Ship faster with production‑ready utilities that are (much) faster than stock Unity options.
|
|
651
|
+
- Solve common problems: global settings/services, fast spatial queries, auto‑wiring components, robust serialization.
|
|
652
|
+
- 4,000+ tests and diagrams make behavior and trade‑offs clear.
|
|
653
|
+
|
|
654
|
+
Who is this for?
|
|
655
|
+
|
|
656
|
+
- Unity devs who want pragmatic, high‑quality building blocks without adopting a full framework.
|
|
657
|
+
- Teams that value performance, determinism, and predictable editor tooling.
|
|
658
|
+
|
|
659
|
+
Install in 60 seconds
|
|
660
|
+
|
|
661
|
+
```json
|
|
662
|
+
// Packages/manifest.json
|
|
663
|
+
{
|
|
664
|
+
"dependencies": {
|
|
665
|
+
"com.wallstop-studios.unity-helpers": "https://github.com/wallstop/unity-helpers.git"
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
First 5 minutes: three quick wins
|
|
671
|
+
|
|
672
|
+
- Random: swap in a faster, seedable RNG
|
|
673
|
+
|
|
674
|
+
```csharp
|
|
675
|
+
using WallstopStudios.UnityHelpers.Core.Random;
|
|
676
|
+
IRandom rng = PRNG.Instance;
|
|
677
|
+
int damage = rng.Next(10, 20);
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
- Relational wiring: stop writing GetComponent
|
|
681
|
+
|
|
682
|
+
```csharp
|
|
683
|
+
using WallstopStudios.UnityHelpers.Core.Attributes;
|
|
684
|
+
public class Player : MonoBehaviour
|
|
685
|
+
{
|
|
686
|
+
[SiblingComponent] SpriteRenderer sprite;
|
|
687
|
+
void Awake() => this.AssignRelationalComponents();
|
|
688
|
+
|
|
689
|
+
> Need DI integration? Optional assemblies automatically light up when Zenject or VContainer is installed, exposing helpers like `RelationalComponentsInstaller` and `RegisterRelationalComponents()` so relational fields are assigned during container initialization.
|
|
690
|
+
|
|
691
|
+
}
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
- Spatial queries: O(log n) instead of O(n)
|
|
695
|
+
|
|
696
|
+
```csharp
|
|
697
|
+
using WallstopStudios.UnityHelpers.Core.DataStructure;
|
|
698
|
+
var tree = new QuadTree2D<Vector2>(points, p => p);
|
|
699
|
+
var results = new List<Vector2>();
|
|
700
|
+
tree.GetElementsInRange(playerPos, 10f, results);
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
Pick the right spatial structure (2D)
|
|
704
|
+
|
|
705
|
+
- Broad‑phase, many moving points: QuadTree2D
|
|
706
|
+
- Nearest neighbors on static points: KDTree2D (Balanced)
|
|
707
|
+
- Fast builds, good‑enough queries: KDTree2D (Unbalanced)
|
|
708
|
+
- Objects with size, bounds queries: RTree2D
|
|
709
|
+
|
|
710
|
+
Next steps
|
|
711
|
+
|
|
712
|
+
- Browse the Guides: Singletons, Relational Components, Spatial Trees 2D/3D, Serialization
|
|
713
|
+
- Skim the Performance pages for realistic expectations
|
|
714
|
+
- Use the Editor Tools to automate common art/content workflows
|
|
715
|
+
|
|
716
|
+
## Table of Contents
|
|
717
|
+
|
|
718
|
+
- [Quick Onramp](#quick-onramp)
|
|
719
|
+
- [Why Unity Helpers?](#why-unity-helpers)
|
|
720
|
+
- [Key Features](#key-features)
|
|
721
|
+
- [Installation](#installation)
|
|
722
|
+
- [Compatibility](#compatibility)
|
|
723
|
+
- [Quick Start Guide](#quick-start-guide)
|
|
724
|
+
- [Random Number Generation](#random-number-generation)
|
|
725
|
+
- [Auto Component Discovery](#auto-component-discovery)
|
|
726
|
+
- [Spatial Queries](#spatial-queries)
|
|
727
|
+
- [Effects in One Minute](#effects-in-one-minute)
|
|
728
|
+
- [Serialization in One Minute](#serialization-in-one-minute)
|
|
729
|
+
- [Core Features](#core-features)
|
|
730
|
+
- [Random Number Generators](#random-number-generators)
|
|
731
|
+
- [Spatial Trees](#spatial-trees)
|
|
732
|
+
- [Effects, Attributes, and Tags](#effects-attributes-and-tags)
|
|
733
|
+
- [Component Attributes](#component-attributes)
|
|
734
|
+
- [Relational Components Guide](#relational-components-guide)
|
|
735
|
+
- [Serialization](#serialization)
|
|
736
|
+
- [Serialization Guide (Full)](SERIALIZATION.md)
|
|
737
|
+
- [Data Structures](#data-structures)
|
|
738
|
+
- [Editor Tools](#editor-tools)
|
|
739
|
+
- [Use Cases & Examples](#use-cases--examples)
|
|
740
|
+
- [Performance](#performance)
|
|
741
|
+
- [Contributing](#contributing)
|
|
742
|
+
- [License](#license)
|
|
743
|
+
- [Relational Components Guide](#relational-components-guide)
|
|
744
|
+
- [API Index](#api-index)
|
|
745
|
+
- [Buffering Pattern](#buffering-pattern)
|
|
746
|
+
- [Docs Index](#docs-index)
|
|
747
|
+
|
|
748
|
+
## Why Unity Helpers?
|
|
749
|
+
|
|
750
|
+
Unity Helpers was built to solve common game development challenges with **performance-first** solutions:
|
|
751
|
+
|
|
752
|
+
- 🚀 **10-15x faster** random number generation compared to Unity's built-in Random
|
|
753
|
+
- 🌳 **O(log n)** spatial queries instead of O(n) linear searches
|
|
754
|
+
- 🔧 **20+ editor tools** to streamline your workflow
|
|
755
|
+
- 📦 **Zero dependencies** - just import and use
|
|
756
|
+
- ✅ **Production-tested** in shipped games
|
|
757
|
+
- 🧪 **5000+ test cases** cover most of the public API and run before each release to catch regressions and prevent bugs
|
|
758
|
+
|
|
759
|
+
## Key Features
|
|
760
|
+
|
|
761
|
+
### High-Performance Random Number Generators
|
|
762
|
+
|
|
763
|
+
**🎯 The Problem Unity.Random Solves Poorly:**
|
|
764
|
+
|
|
765
|
+
- Slow (~65-85M ops/sec) - becomes a bottleneck in proc-gen and particle systems
|
|
766
|
+
- Not seedable - impossible to create deterministic gameplay or replays
|
|
767
|
+
- Not thread-safe - can only use on main thread
|
|
768
|
+
- Basic API - missing weighted selection, distributions, noise generation
|
|
769
|
+
|
|
770
|
+
**⚡ Unity Helpers Solution - PRNG.Instance:**
|
|
771
|
+
|
|
772
|
+
- **10-15x faster** (655-885M ops/sec) - [See benchmarks](RANDOM_PERFORMANCE.md)
|
|
773
|
+
- **Fully seedable** - same seed = identical results (perfect for networking, replays, proc-gen)
|
|
774
|
+
- **Thread-safe** - via thread-local instances, use anywhere
|
|
775
|
+
- **Game-ready API** - weighted selection, Gaussian distributions, Perlin noise, and more
|
|
776
|
+
|
|
777
|
+
#### Quick Win Example
|
|
778
|
+
|
|
779
|
+
```csharp
|
|
780
|
+
using WallstopStudios.UnityHelpers.Core.Random;
|
|
781
|
+
using WallstopStudios.UnityHelpers.Core.Extension;
|
|
782
|
+
|
|
783
|
+
// ❌ OLD WAY (Slow + Not Reproducible)
|
|
784
|
+
void SpawnEnemies()
|
|
785
|
+
{
|
|
786
|
+
for (int i = 0; i < 1000; i++)
|
|
787
|
+
{
|
|
788
|
+
Vector2 pos = new Vector2(Random.value * 100, Random.value * 100);
|
|
789
|
+
// No way to reproduce this exact pattern!
|
|
790
|
+
// Slow - each call is expensive
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// ✅ NEW WAY (10x Faster + Fully Deterministic)
|
|
795
|
+
void SpawnEnemies(int levelSeed)
|
|
796
|
+
{
|
|
797
|
+
IRandom rng = new IllusionFlow(seed: levelSeed);
|
|
798
|
+
|
|
799
|
+
for (int i = 0; i < 1000; i++)
|
|
800
|
+
{
|
|
801
|
+
Vector2 pos = rng.NextVector2() * 100f;
|
|
802
|
+
// Same seed = identical enemy layout every time!
|
|
803
|
+
// 10x faster execution
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
#### When This Really Matters
|
|
809
|
+
|
|
810
|
+
1. **Procedural Generation** - Levels, dungeons, terrain (thousands of random rolls per generation)
|
|
811
|
+
2. **Networked Multiplayer** - Clients generate identical results from shared seeds
|
|
812
|
+
3. **Replay Systems** - Reproduce exact gameplay sequences frame-by-frame
|
|
813
|
+
4. **Particle Systems** - Hundreds of random values per frame without GC
|
|
814
|
+
5. **Performance-Critical Loops** - Every microsecond counts in tight loops
|
|
815
|
+
|
|
816
|
+
#### Rich API for Game Development
|
|
817
|
+
|
|
818
|
+
Beyond basic `NextFloat()`, get game-ready features out of the box:
|
|
819
|
+
|
|
820
|
+
```csharp
|
|
821
|
+
IRandom rng = PRNG.Instance;
|
|
822
|
+
|
|
823
|
+
// Weighted random selection (loot tables, spawn weights)
|
|
824
|
+
string[] loot = { "Common", "Rare", "Epic", "Legendary" };
|
|
825
|
+
float[] weights = { 0.60f, 0.25f, 0.10f, 0.05f };
|
|
826
|
+
string drop = loot[rng.NextWeightedIndex(weights)];
|
|
827
|
+
|
|
828
|
+
// Gaussian distribution (natural-looking randomness for damage variance, spawn positions)
|
|
829
|
+
float damage = rng.NextGaussian(mean: 100f, stdDev: 15f);
|
|
830
|
+
|
|
831
|
+
// Perlin noise maps (terrain generation, texture synthesis)
|
|
832
|
+
float[,] heightMap = new float[256, 256];
|
|
833
|
+
rng.NextNoiseMap(heightMap, octaves: 4, persistence: 0.5f);
|
|
834
|
+
|
|
835
|
+
// Collections (shuffling, random picks)
|
|
836
|
+
List<Enemy> enemies = GetAllEnemies();
|
|
837
|
+
rng.Shuffle(enemies); // Fisher-Yates shuffle
|
|
838
|
+
Enemy target = rng.NextOf(enemies); // Random element
|
|
839
|
+
|
|
840
|
+
// Unity types (spawning, effects)
|
|
841
|
+
Vector3 randomPos = rng.NextVector3() * spawnRadius;
|
|
842
|
+
Color randomColor = rng.NextColor();
|
|
843
|
+
Quaternion randomRot = rng.NextRotation();
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
#### Available Generators
|
|
847
|
+
|
|
848
|
+
| Generator | Speed | Quality | Use Case |
|
|
849
|
+
| ------------------------------- | --------- | --------- | ----------------------------- |
|
|
850
|
+
| **IllusionFlow** ⭐ | Fast | Good | Default (via PRNG.Instance) |
|
|
851
|
+
| **PcgRandom** | Very Fast | Excellent | Explicit seeding, determinism |
|
|
852
|
+
| **RomuDuo** | Fastest | Good | Maximum speed needed |
|
|
853
|
+
| **LinearCongruentialGenerator** | Fastest | Fair | Simple, fast generation |
|
|
854
|
+
|
|
855
|
+
⭐ **Recommended**: Use `PRNG.Instance` (currently IllusionFlow) for the best balance of speed, quality, and ease of use.
|
|
856
|
+
|
|
857
|
+
[📊 Full Performance Benchmarks](RANDOM_PERFORMANCE.md)
|
|
858
|
+
|
|
859
|
+
### Spatial Trees for Fast Queries
|
|
860
|
+
|
|
861
|
+
- **2D & 3D spatial trees** (QuadTree, OctTree, KDTree, RTree)
|
|
862
|
+
- Perfect for collision detection, AI, visibility culling
|
|
863
|
+
- **Massive performance gains** for games with many objects
|
|
864
|
+
- Immutable trees with O(log n) query performance
|
|
865
|
+
- Note on stability and semantics:
|
|
866
|
+
- 2D: QuadTree2D and KdTree2D (balanced/unbalanced) return the same results for the same inputs/queries; they differ only in performance characteristics. RTree2D indexes rectangles (bounds), so results differ for sized objects.
|
|
867
|
+
- 3D: KdTree3D (balanced/unbalanced) and OctTree3D can yield different results for the same inputs/queries due to boundary, tie‑breaking, and traversal semantics. RTree3D indexes 3D bounds and differs by design. See Spatial Tree Semantics for details.
|
|
868
|
+
|
|
869
|
+
### Powerful Component Attributes
|
|
870
|
+
|
|
871
|
+
- `[ParentComponent]`, `[ChildComponent]`, `[SiblingComponent]` - Auto-wire components
|
|
872
|
+
- `[ValidateAssignment]` - Catch missing references at edit time
|
|
873
|
+
- `[DxReadOnly]` - Display calculated values in inspector
|
|
874
|
+
- `[WShowIf]` - Conditional inspector fields
|
|
875
|
+
|
|
876
|
+
See the in-depth guide: [Relational Components](RELATIONAL_COMPONENTS.md).
|
|
877
|
+
|
|
878
|
+
### 20+ Editor Tools
|
|
879
|
+
|
|
880
|
+
- **Sprite tools**: Cropper, Atlas Generator, Animation Editor, Animation Creator (one‑click bulk from naming patterns)
|
|
881
|
+
- **Texture tools**: Blur, Resize, Settings Applier
|
|
882
|
+
- **Validation**: Prefab Checker, Animation Event Editor
|
|
883
|
+
- **Automation**: ScriptableObject Singleton Creator
|
|
884
|
+
- [Full Editor Tools Documentation](EDITOR_TOOLS_GUIDE.md)
|
|
885
|
+
|
|
886
|
+
### Core Math & Extensions
|
|
887
|
+
|
|
888
|
+
- Numeric helpers, geometry primitives, Unity extensions, colors, collections, strings, directions.
|
|
889
|
+
- See the guide: [Core Math & Extensions](MATH_AND_EXTENSIONS.md).
|
|
890
|
+
|
|
891
|
+
#### At a Glance
|
|
892
|
+
|
|
893
|
+
- `PositiveMod`, `WrappedAdd` — Safe cyclic arithmetic for indices/angles. See: [Numeric Helpers](MATH_AND_EXTENSIONS.md#numeric-helpers).
|
|
894
|
+
- `LineHelper.Simplify` — Reduce polyline vertices with Douglas–Peucker. See: [Geometry](MATH_AND_EXTENSIONS.md#geometry).
|
|
895
|
+
- `Line2D.Intersects` — Robust 2D segment intersection and closest-point helpers. See: [Geometry](MATH_AND_EXTENSIONS.md#geometry).
|
|
896
|
+
- `RectTransform.GetWorldRect` — Axis-aligned world bounds for rotated UI. See: [Unity Extensions](MATH_AND_EXTENSIONS.md#unity-extensions).
|
|
897
|
+
- `Camera.OrthographicBounds` — Compute visible world bounds for ortho cameras. See: [Unity Extensions](MATH_AND_EXTENSIONS.md#unity-extensions).
|
|
898
|
+
- `Color.GetAverageColor` — LAB/HSV/Weighted/Dominant color averaging. See: [Color Utilities](MATH_AND_EXTENSIONS.md#color-utilities).
|
|
899
|
+
- `IEnumerable.Infinite` — Cycle sequences without extra allocations. See: [Collections](MATH_AND_EXTENSIONS.md#collections).
|
|
900
|
+
- `StringExtensions.LevenshteinDistance` — Edit distance for fuzzy matching. See: [Strings](MATH_AND_EXTENSIONS.md#strings).
|
|
901
|
+
|
|
902
|
+
<a id="singleton-utilities-odin-compatible"></a>
|
|
903
|
+
|
|
904
|
+
### Singleton Utilities (ODIN‑compatible)
|
|
905
|
+
|
|
906
|
+
- `RuntimeSingleton<T>` — Global component singleton with optional cross‑scene persistence. See the guide: [Singleton Utilities](SINGLETONS.md).
|
|
907
|
+
- `ScriptableObjectSingleton<T>` — Global settings/data singleton loaded from `Resources/`, auto‑created by the editor tool. See the guide: [Singleton Utilities](SINGLETONS.md) and the tool: [ScriptableObject Singleton Creator](EDITOR_TOOLS_GUIDE.md#scriptableobject-singleton-creator).
|
|
908
|
+
|
|
909
|
+
## Docs Index
|
|
910
|
+
|
|
911
|
+
**Start Here**
|
|
912
|
+
|
|
913
|
+
- 🚀 Getting Started — [Getting Started Guide](GETTING_STARTED.md)
|
|
914
|
+
- 🔍 Feature Index — [Complete A-Z Index](INDEX.md)
|
|
915
|
+
- 📖 Glossary — [Term Definitions](GLOSSARY.md)
|
|
916
|
+
|
|
917
|
+
**Core Guides**
|
|
918
|
+
|
|
919
|
+
- Serialization Guide — [Serialization](SERIALIZATION.md)
|
|
920
|
+
- Editor Tools Guide — [Editor Tools](EDITOR_TOOLS_GUIDE.md)
|
|
921
|
+
- Math & Extensions — [Core Math & Extensions](MATH_AND_EXTENSIONS.md)
|
|
922
|
+
- Singletons — [Singleton Utilities](SINGLETONS.md)
|
|
923
|
+
- Relational Components — [Relational Components](RELATIONAL_COMPONENTS.md)
|
|
924
|
+
- Effects System — [Effects System](EFFECTS_SYSTEM.md)
|
|
925
|
+
- Data Structures — [Data Structures](DATA_STRUCTURES.md)
|
|
926
|
+
|
|
927
|
+
**Spatial Trees**
|
|
928
|
+
|
|
929
|
+
- 2D Spatial Trees Guide — [2D Spatial Trees Guide](SPATIAL_TREES_2D_GUIDE.md)
|
|
930
|
+
- 3D Spatial Trees Guide — [3D Spatial Trees Guide](SPATIAL_TREES_3D_GUIDE.md)
|
|
931
|
+
- Spatial Tree Semantics — [Spatial Tree Semantics](SPATIAL_TREE_SEMANTICS.md)
|
|
932
|
+
- Spatial Tree 2D Performance — [Spatial Tree 2D Performance](SPATIAL_TREE_2D_PERFORMANCE.md)
|
|
933
|
+
- Spatial Tree 3D Performance — [Spatial Tree 3D Performance](SPATIAL_TREE_3D_PERFORMANCE.md)
|
|
934
|
+
- Hulls (Convex vs Concave) — [Hulls](HULLS.md)
|
|
935
|
+
|
|
936
|
+
**Performance & Reference**
|
|
937
|
+
|
|
938
|
+
- Random Performance — [Random Performance](RANDOM_PERFORMANCE.md)
|
|
939
|
+
- Reflection Helpers — [Reflection Helpers](REFLECTION_HELPERS.md)
|
|
940
|
+
|
|
941
|
+
**Project Info**
|
|
942
|
+
|
|
943
|
+
- Changelog — [Changelog](CHANGELOG.md)
|
|
944
|
+
- License — [License](LICENSE.md)
|
|
945
|
+
- Third‑Party Notices — [Third‑Party Notices](THIRD_PARTY_NOTICES.md)
|
|
946
|
+
|
|
947
|
+
## Installation
|
|
948
|
+
|
|
949
|
+
### As Unity Package (Recommended)
|
|
950
|
+
|
|
951
|
+
1. Open Unity Package Manager
|
|
952
|
+
2. _(Optional)_ Enable **Pre-release packages** for cutting-edge builds
|
|
953
|
+
3. Click the **+** dropdown → **Add package from git URL...**
|
|
954
|
+
4. Enter: `https://github.com/wallstop/unity-helpers.git`
|
|
955
|
+
|
|
956
|
+
**OR** add to your `manifest.json`:
|
|
957
|
+
|
|
958
|
+
```json
|
|
959
|
+
{
|
|
960
|
+
"dependencies": {
|
|
961
|
+
"com.wallstop-studios.unity-helpers": "https://github.com/wallstop/unity-helpers.git"
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
### From NPM Registry
|
|
967
|
+
|
|
968
|
+
1. Open Unity Package Manager
|
|
969
|
+
2. _(Optional)_ Enable **Pre-release packages**
|
|
970
|
+
3. Open **Advanced Package Settings** (gear icon)
|
|
971
|
+
4. Add a new **Scoped Registry**:
|
|
972
|
+
- **Name**: `NPM`
|
|
973
|
+
- **URL**: `https://registry.npmjs.org`
|
|
974
|
+
- **Scope(s)**: `com.wallstop-studios.unity-helpers`
|
|
975
|
+
5. Search for and install `com.wallstop-studios.unity-helpers`
|
|
976
|
+
|
|
977
|
+
### From Source
|
|
978
|
+
|
|
979
|
+
1. [Download the latest release](https://github.com/wallstop/unity-helpers/releases) or clone this repository
|
|
980
|
+
2. Copy the contents to your project's `Assets` folder
|
|
981
|
+
3. Unity will automatically import the package
|
|
982
|
+
|
|
983
|
+
## Compatibility
|
|
984
|
+
|
|
985
|
+
| Unity Version | Built-In | URP | HDRP |
|
|
986
|
+
| ------------- | -------------------- | -------------------- | -------------------- |
|
|
987
|
+
| 2021 | Likely, but untested | Likely, but untested | Likely, but untested |
|
|
988
|
+
| 2022 | ✅ Compatible | ✅ Compatible | ✅ Compatible |
|
|
989
|
+
| 2023 | ✅ Compatible | ✅ Compatible | ✅ Compatible |
|
|
990
|
+
| Unity 6 | ✅ Compatible | ✅ Compatible | ✅ Compatible |
|
|
991
|
+
|
|
992
|
+
### Platform Support
|
|
993
|
+
|
|
994
|
+
Unity Helpers is **fully multiplatform compatible** including:
|
|
995
|
+
|
|
996
|
+
- ✅ **WebGL** - Full support with optimized SINGLE_THREADED hot paths
|
|
997
|
+
- ✅ **IL2CPP** - Tested and compatible with ahead-of-time compilation
|
|
998
|
+
- ✅ **Mobile** (iOS, Android) - Production-ready with IL2CPP
|
|
999
|
+
- ✅ **Desktop** (Windows, macOS, Linux) - Full threading support
|
|
1000
|
+
- ✅ **Consoles** - IL2CPP compatible
|
|
1001
|
+
|
|
1002
|
+
**Requirements:**
|
|
1003
|
+
|
|
1004
|
+
- **.NET Standard 2.1** - Required for core library features
|
|
1005
|
+
|
|
1006
|
+
### WebGL and Single-Threaded Optimization
|
|
1007
|
+
|
|
1008
|
+
Unity Helpers includes a `SINGLE_THREADED` scripting define symbol for WebGL and other single-threaded environments. When enabled, the library automatically uses optimized code paths that eliminate threading overhead:
|
|
1009
|
+
|
|
1010
|
+
**Optimized systems with SINGLE_THREADED:**
|
|
1011
|
+
|
|
1012
|
+
- **Buffers & Pooling** - Uses `Stack<T>` and `Dictionary<T>` instead of `ConcurrentBag<T>` and `ConcurrentDictionary<T>`
|
|
1013
|
+
- **Random Number Generation** - Static instances instead of `ThreadLocal<T>`
|
|
1014
|
+
- **Reflection Caches** - Non-concurrent dictionaries for faster lookups
|
|
1015
|
+
- **Thread Pools** - SingleThreadedThreadPool disabled (not needed on WebGL)
|
|
1016
|
+
|
|
1017
|
+
**How to enable:**
|
|
1018
|
+
|
|
1019
|
+
Unity automatically defines `UNITY_WEBGL` for WebGL builds. To enable SINGLE_THREADED optimization:
|
|
1020
|
+
|
|
1021
|
+
1. Go to **Project Settings > Player > Other Settings > Scripting Define Symbols**
|
|
1022
|
+
2. Add `SINGLE_THREADED` for WebGL platform
|
|
1023
|
+
3. Or use in your `csc.rsp` file: `-define:SINGLE_THREADED`
|
|
1024
|
+
|
|
1025
|
+
**Performance impact:** 10-20% faster hot path operations on single-threaded platforms by avoiding unnecessary synchronization overhead.
|
|
1026
|
+
|
|
1027
|
+
### IL2CPP and Code Stripping Considerations
|
|
1028
|
+
|
|
1029
|
+
⚠️ **Important for IL2CPP builds (WebGL, Mobile, Consoles):**
|
|
1030
|
+
|
|
1031
|
+
Some features in Unity Helpers use reflection internally (particularly **Protobuf serialization** and **ReflectionHelpers**). IL2CPP's managed code stripping may remove types/members that are only accessed via reflection, causing runtime errors.
|
|
1032
|
+
|
|
1033
|
+
**Symptoms of stripping issues:**
|
|
1034
|
+
|
|
1035
|
+
- `NullReferenceException` or `TypeLoadException` during deserialization
|
|
1036
|
+
- Missing fields after Protobuf deserialization
|
|
1037
|
+
- Reflection helpers failing to find types at runtime
|
|
1038
|
+
|
|
1039
|
+
**Solution: Use link.xml to preserve required types**
|
|
1040
|
+
|
|
1041
|
+
Create a `link.xml` file in your `Assets` folder to prevent stripping:
|
|
1042
|
+
|
|
1043
|
+
```xml
|
|
1044
|
+
<linker>
|
|
1045
|
+
<!-- Preserve your serialized types -->
|
|
1046
|
+
<assembly fullname="Assembly-CSharp">
|
|
1047
|
+
<type fullname="MyNamespace.PlayerSave" preserve="all"/>
|
|
1048
|
+
<type fullname="MyNamespace.InventoryData" preserve="all"/>
|
|
1049
|
+
<!-- Add all Protobuf-serialized types here -->
|
|
1050
|
+
</assembly>
|
|
1051
|
+
|
|
1052
|
+
<!-- Preserve Unity Helpers if needed -->
|
|
1053
|
+
<assembly fullname="WallstopStudios.UnityHelpers.Runtime" preserve="all"/>
|
|
1054
|
+
</linker>
|
|
1055
|
+
```
|
|
1056
|
+
|
|
1057
|
+
**Best practices:**
|
|
1058
|
+
|
|
1059
|
+
- ✅ **Always test IL2CPP builds** - Development builds don't use stripping, so bugs only appear in release builds
|
|
1060
|
+
- ✅ **Test on target platform** - WebGL stripping behaves differently than iOS/Android
|
|
1061
|
+
- ✅ **Use link.xml for all Protobuf types** - Any type with `[ProtoContract]` should be preserved
|
|
1062
|
+
- ✅ **Verify after every schema change** - Adding new serialized types requires updating link.xml
|
|
1063
|
+
- ✅ **Check logs for stripping warnings** - Unity logs which types are stripped during build
|
|
1064
|
+
|
|
1065
|
+
**When you don't need link.xml:**
|
|
1066
|
+
|
|
1067
|
+
- JSON serialization (uses source-generated converters, not reflection)
|
|
1068
|
+
- Spatial trees and data structures (no reflection used)
|
|
1069
|
+
- Most helper methods (compiled ahead-of-time)
|
|
1070
|
+
|
|
1071
|
+
**Related documentation:**
|
|
1072
|
+
|
|
1073
|
+
- [Unity Manual: Managed Code Stripping](https://docs.unity3d.com/Manual/ManagedCodeStripping.html)
|
|
1074
|
+
- [Protobuf-net and IL2CPP](https://github.com/protobuf-net/protobuf-net#il2cpp)
|
|
1075
|
+
- [Serialization Guide: IL2CPP Warning](SERIALIZATION.md#️-il2cpp-and-code-stripping-warning)
|
|
1076
|
+
- [Reflection Helpers: IL2CPP Warning](REFLECTION_HELPERS.md#️-il2cpp-code-stripping-considerations)
|
|
1077
|
+
|
|
1078
|
+
## Serialization
|
|
1079
|
+
|
|
1080
|
+
- Formats: JSON (System.Text.Json), Protobuf (protobuf-net), SystemBinary (legacy)
|
|
1081
|
+
- Unity-aware JSON converters (Vector2/3/4, Color, Matrix4x4, Type, GameObject)
|
|
1082
|
+
- Pooled buffers to minimize GC; byte[] APIs for hot paths
|
|
1083
|
+
|
|
1084
|
+
JSON profiles
|
|
1085
|
+
|
|
1086
|
+
- Normal — robust defaults (case-insensitive, includes fields, comments/trailing commas allowed)
|
|
1087
|
+
- Pretty — human-friendly, indented
|
|
1088
|
+
- Fast — strict, minimal with Unity converters (case-sensitive, strict numbers, no comments/trailing commas, IncludeFields=false)
|
|
1089
|
+
- FastPOCO — strict, minimal, no Unity converters; best for pure POCO graphs
|
|
1090
|
+
|
|
1091
|
+
Usage
|
|
1092
|
+
|
|
1093
|
+
```csharp
|
|
1094
|
+
using WallstopStudios.UnityHelpers.Core.Serialization;
|
|
1095
|
+
|
|
1096
|
+
var normal = Serializer.CreateNormalJsonOptions();
|
|
1097
|
+
var pretty = Serializer.CreatePrettyJsonOptions();
|
|
1098
|
+
var fast = Serializer.CreateFastJsonOptions();
|
|
1099
|
+
var fastPOCO = Serializer.CreateFastPocoJsonOptions();
|
|
1100
|
+
|
|
1101
|
+
byte[] buf = null;
|
|
1102
|
+
Serializer.JsonSerialize(model, fast, ref buf); // pooled, minimal allocs
|
|
1103
|
+
Serializer.JsonSerialize(model, fast, sizeHint: 512*1024, ref buf); // preallocate for large outputs
|
|
1104
|
+
var rt = Serializer.JsonDeserialize<MyType>(buf, null, fast); // span-based; no string alloc
|
|
1105
|
+
```
|
|
1106
|
+
|
|
1107
|
+
When to use what
|
|
1108
|
+
|
|
1109
|
+
- Save/configs: Normal or Pretty
|
|
1110
|
+
- Hot loops/large arrays: Fast or FastPOCO (POCO-only graphs)
|
|
1111
|
+
- Mixed graphs with Unity types: Fast
|
|
1112
|
+
|
|
1113
|
+
See the full guide for trade-offs, tips, and examples: [Serialization Guide](SERIALIZATION.md)
|
|
1114
|
+
|
|
1115
|
+
## Quick Start Guide
|
|
1116
|
+
|
|
1117
|
+
### Random Number Generation
|
|
1118
|
+
|
|
1119
|
+
Replace Unity's Random with high-performance alternatives:
|
|
1120
|
+
|
|
1121
|
+
```csharp
|
|
1122
|
+
using System;
|
|
1123
|
+
using UnityEngine;
|
|
1124
|
+
using WallstopStudios.UnityHelpers.Core.Random;
|
|
1125
|
+
using WallstopStudios.UnityHelpers.Core.Extension; // extension APIs like NextVector2(), NextWeightedIndex()
|
|
1126
|
+
|
|
1127
|
+
// Use the recommended default (currently IllusionFlow)
|
|
1128
|
+
IRandom random = PRNG.Instance;
|
|
1129
|
+
|
|
1130
|
+
// Basic random values
|
|
1131
|
+
float chance = random.NextFloat(); // 0.0f to 1.0f
|
|
1132
|
+
int damage = random.Next(10, 20); // 10 to 19
|
|
1133
|
+
bool critical = random.NextBool(); // true or false
|
|
1134
|
+
|
|
1135
|
+
// Advanced features
|
|
1136
|
+
Vector2 position = random.NextVector2(); // Random 2D position (extension method)
|
|
1137
|
+
Guid playerId = random.NextGuid(); // UUIDv4
|
|
1138
|
+
float gaussian = random.NextGaussian(); // Normal distribution
|
|
1139
|
+
|
|
1140
|
+
// Random selection
|
|
1141
|
+
string[] lootTable = { "Sword", "Shield", "Potion" };
|
|
1142
|
+
string item = random.NextOf(lootTable);
|
|
1143
|
+
|
|
1144
|
+
// Weighted bool
|
|
1145
|
+
float probability = 0.7f;
|
|
1146
|
+
bool lucky = random.NextBool(probability);
|
|
1147
|
+
|
|
1148
|
+
// Noise generation
|
|
1149
|
+
float[,] noiseMap = new float[256, 256];
|
|
1150
|
+
random.NextNoiseMap(noiseMap, octaves: 4);
|
|
1151
|
+
```
|
|
1152
|
+
|
|
1153
|
+
**Why use PRNG.Instance?**
|
|
1154
|
+
|
|
1155
|
+
- 10-15x faster than Unity.Random
|
|
1156
|
+
- Seedable for deterministic gameplay
|
|
1157
|
+
- Thread-safe access (uses a thread-local instance)
|
|
1158
|
+
- Extensive API for common patterns
|
|
1159
|
+
|
|
1160
|
+
[📊 View Random Performance Benchmarks](RANDOM_PERFORMANCE.md)
|
|
1161
|
+
|
|
1162
|
+
### Auto Component Discovery
|
|
1163
|
+
|
|
1164
|
+
Stop writing GetComponent calls everywhere:
|
|
1165
|
+
|
|
1166
|
+
```csharp
|
|
1167
|
+
using WallstopStudios.UnityHelpers.Core.Attributes;
|
|
1168
|
+
using UnityEngine;
|
|
1169
|
+
|
|
1170
|
+
public class Player : MonoBehaviour
|
|
1171
|
+
{
|
|
1172
|
+
// Automatically finds SpriteRenderer on same GameObject
|
|
1173
|
+
[SiblingComponent]
|
|
1174
|
+
private SpriteRenderer spriteRenderer;
|
|
1175
|
+
|
|
1176
|
+
// Finds Rigidbody2D on same GameObject, but it's optional
|
|
1177
|
+
[SiblingComponent(Optional = true)]
|
|
1178
|
+
private Rigidbody2D rigidbody;
|
|
1179
|
+
|
|
1180
|
+
// Finds Camera in parent hierarchy
|
|
1181
|
+
[ParentComponent]
|
|
1182
|
+
private Camera parentCamera;
|
|
1183
|
+
|
|
1184
|
+
// Only search ancestors, not siblings
|
|
1185
|
+
[ParentComponent(OnlyAncestors = true)]
|
|
1186
|
+
private Transform[] parentTransforms;
|
|
1187
|
+
|
|
1188
|
+
// Finds all PolygonCollider2D in children
|
|
1189
|
+
[ChildComponent]
|
|
1190
|
+
private List<PolygonCollider2D> childColliders;
|
|
1191
|
+
|
|
1192
|
+
// Only search descendants
|
|
1193
|
+
[ChildComponent(OnlyDescendants = true)]
|
|
1194
|
+
private EdgeCollider2D edgeCollider;
|
|
1195
|
+
|
|
1196
|
+
private void Awake()
|
|
1197
|
+
{
|
|
1198
|
+
// One call wires up everything!
|
|
1199
|
+
this.AssignRelationalComponents();
|
|
1200
|
+
|
|
1201
|
+
// All fields are now assigned (or logged errors if missing)
|
|
1202
|
+
spriteRenderer.color = Color.red;
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
```
|
|
1206
|
+
|
|
1207
|
+
**Benefits:**
|
|
1208
|
+
|
|
1209
|
+
- Cleaner, more declarative code
|
|
1210
|
+
- Safer defaults (required by default; opt-in `Optional = true`)
|
|
1211
|
+
- Filters by tag/name, limit results, control depth, support interfaces
|
|
1212
|
+
- Works with single fields, arrays, `List<T>`, and `HashSet<T>`
|
|
1213
|
+
- Descriptive error logging for missing required components
|
|
1214
|
+
- Honors `IncludeInactive` (include disabled/inactive when true)
|
|
1215
|
+
|
|
1216
|
+
For a complete walkthrough with recipes, FAQs, and troubleshooting, see [Relational Components](RELATIONAL_COMPONENTS.md) (Troubleshooting: [Tips & Troubleshooting](RELATIONAL_COMPONENTS.md#troubleshooting)).
|
|
1217
|
+
|
|
1218
|
+
### Spatial Queries
|
|
1219
|
+
|
|
1220
|
+
Fast spatial lookups for AI, collision detection, and more:
|
|
1221
|
+
|
|
1222
|
+
```csharp
|
|
1223
|
+
using WallstopStudios.UnityHelpers.Core.DataStructure;
|
|
1224
|
+
using UnityEngine;
|
|
1225
|
+
|
|
1226
|
+
public class EnemyManager : MonoBehaviour
|
|
1227
|
+
{
|
|
1228
|
+
private QuadTree2D<Enemy> enemyTree;
|
|
1229
|
+
|
|
1230
|
+
void Start()
|
|
1231
|
+
{
|
|
1232
|
+
// Build tree from all enemies
|
|
1233
|
+
Enemy[] enemies = FindObjectsOfType<Enemy>();
|
|
1234
|
+
enemyTree = new QuadTree2D<Enemy>(enemies, e => e.transform.position);
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
// Find all enemies in radius (O(log n) instead of O(n))
|
|
1238
|
+
public List<Enemy> GetEnemiesInRange(Vector2 position, float radius)
|
|
1239
|
+
{
|
|
1240
|
+
List<Enemy> results = new();
|
|
1241
|
+
enemyTree.GetElementsInRange(position, radius, results);
|
|
1242
|
+
return results;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
// Find enemies in a rectangular area
|
|
1246
|
+
public List<Enemy> GetEnemiesInArea(Bounds area)
|
|
1247
|
+
{
|
|
1248
|
+
List<Enemy> results = new();
|
|
1249
|
+
enemyTree.GetElementsInBounds(area, results);
|
|
1250
|
+
return results;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
// Find nearest enemies fast
|
|
1254
|
+
public List<Enemy> GetNearestEnemies(Vector2 position, int count)
|
|
1255
|
+
{
|
|
1256
|
+
List<Enemy> results = new();
|
|
1257
|
+
enemyTree.GetApproximateNearestNeighbors(position, count, results);
|
|
1258
|
+
return results;
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
**Important:** Spatial trees are **immutable** - rebuild them when positions change.
|
|
1264
|
+
|
|
1265
|
+
[📊 View 2D Performance Benchmarks](SPATIAL_TREE_2D_PERFORMANCE.md) | [📊 View 3D Performance Benchmarks](SPATIAL_TREE_3D_PERFORMANCE.md)
|
|
1266
|
+
|
|
1267
|
+
For zero‑alloc queries and stable GC, see the [Buffering Pattern](#buffering-pattern).
|
|
1268
|
+
|
|
1269
|
+
### Effects in One Minute
|
|
1270
|
+
|
|
1271
|
+
Author stackable buffs/debuffs as assets and apply/remove at runtime.
|
|
1272
|
+
|
|
1273
|
+
```csharp
|
|
1274
|
+
using WallstopStudios.UnityHelpers.Core.Effects;
|
|
1275
|
+
|
|
1276
|
+
// ScriptableObject: AttributeEffect (create via menu)
|
|
1277
|
+
// Contains: modifications (e.g., Speed x1.5), tags (e.g., "Haste"), duration
|
|
1278
|
+
|
|
1279
|
+
// Apply to a target GameObject
|
|
1280
|
+
EffectHandle? handle = target.ApplyEffect(hasteEffect);
|
|
1281
|
+
|
|
1282
|
+
// Later: remove one stack or all
|
|
1283
|
+
if (handle.HasValue) target.RemoveEffect(handle.Value);
|
|
1284
|
+
target.RemoveAllEffectsWithTag("Haste");
|
|
1285
|
+
```
|
|
1286
|
+
|
|
1287
|
+
Why use it
|
|
1288
|
+
|
|
1289
|
+
- Declarative authoring, automatic stacking/timing/tagging, clean removal.
|
|
1290
|
+
- Cosmetic hooks for VFX/SFX via `CosmeticEffectData`.
|
|
1291
|
+
|
|
1292
|
+
### Serialization in One Minute
|
|
1293
|
+
|
|
1294
|
+
Serialize/deserialize with Unity‑aware JSON profiles; use pooled buffers for hot paths.
|
|
1295
|
+
|
|
1296
|
+
```csharp
|
|
1297
|
+
using WallstopStudios.UnityHelpers.Core.Serialization;
|
|
1298
|
+
|
|
1299
|
+
var opts = Serializer.CreateFastJsonOptions(); // or Pretty/Normal
|
|
1300
|
+
|
|
1301
|
+
// Serialize into a pooled buffer
|
|
1302
|
+
byte[] buf = null;
|
|
1303
|
+
Serializer.JsonSerialize(model, opts, ref buf);
|
|
1304
|
+
|
|
1305
|
+
// Deserialize directly from bytes (no string alloc)
|
|
1306
|
+
var model2 = Serializer.JsonDeserialize<MyType>(buf, null, opts);
|
|
1307
|
+
```
|
|
1308
|
+
|
|
1309
|
+
Tips
|
|
1310
|
+
|
|
1311
|
+
- Pretty/Normal for configs; Fast for hot loops; FastPOCO for pure POCO graphs.
|
|
1312
|
+
- Unity converters handle Vector/Color/Matrix/GameObject references.
|
|
1313
|
+
|
|
1314
|
+
### Choosing Spatial Structures
|
|
1315
|
+
|
|
1316
|
+
- QuadTree2D — Static or semi-static point data in 2D. Great for circular and rectangular queries, approximate kNN. Immutable (rebuild when positions change).
|
|
1317
|
+
- KdTree2D/3D — Excellent nearest-neighbor performance for points. Balanced variant for uniform data; unbalanced for quicker builds. Immutable.
|
|
1318
|
+
- RTree2D — For rectangular/sized objects (sprites, colliders). Great for bounds and radius intersection queries. Immutable.
|
|
1319
|
+
- SpatialHash2D/3D — Many moving objects that are fairly uniformly distributed. Cheap updates; fast approximate neighborhood queries.
|
|
1320
|
+
|
|
1321
|
+
Rules of thumb:
|
|
1322
|
+
|
|
1323
|
+
- Frequent movement? Prefer SpatialHash. Static or batched rebuilds? Use QuadTree/KdTree/RTree.
|
|
1324
|
+
- Query by area/rectangle? RTree2D excels. Nearest neighbors? KdTree. Broad-phase neighbor checks? SpatialHash.
|
|
1325
|
+
|
|
1326
|
+
## Core Features
|
|
1327
|
+
|
|
1328
|
+
### Random Number Generators
|
|
1329
|
+
|
|
1330
|
+
Unity Helpers includes **12 high-quality random number generators**, all implementing a rich `IRandom` interface:
|
|
1331
|
+
|
|
1332
|
+
#### Available Generators
|
|
1333
|
+
|
|
1334
|
+
| Generator | Speed | Quality | Use Case |
|
|
1335
|
+
| ------------------------------- | --------- | --------- | ---------------------------------------- |
|
|
1336
|
+
| **IllusionFlow** ⭐ | Fast | Good | Default choice (via PRNG.Instance) |
|
|
1337
|
+
| **PcgRandom** | Very Fast | Excellent | Deterministic gameplay; explicit seeding |
|
|
1338
|
+
| **RomuDuo** | Fastest | Good | Maximum performance needed |
|
|
1339
|
+
| **LinearCongruentialGenerator** | Fastest | Fair | Simple, fast generation |
|
|
1340
|
+
| **XorShiftRandom** | Very Fast | Good | General purpose |
|
|
1341
|
+
| **XoroShiroRandom** | Very Fast | Good | General purpose |
|
|
1342
|
+
| **SplitMix64** | Very Fast | Good | Initialization, hashing |
|
|
1343
|
+
| **SquirrelRandom** | Moderate | Good | Hash-based generation |
|
|
1344
|
+
| **WyRandom** | Moderate | Good | Hashing applications |
|
|
1345
|
+
| **DotNetRandom** | Moderate | Good | .NET compatibility |
|
|
1346
|
+
| **SystemRandom** | Slow | Good | Backward compatibility |
|
|
1347
|
+
| **UnityRandom** | Very Slow | Good | Unity compatibility |
|
|
1348
|
+
|
|
1349
|
+
⭐ **Recommended**: Use `PRNG.Instance` (currently IllusionFlow)
|
|
1350
|
+
|
|
1351
|
+
#### Rich API
|
|
1352
|
+
|
|
1353
|
+
All generators implement `IRandom` with extensive functionality:
|
|
1354
|
+
|
|
1355
|
+
```csharp
|
|
1356
|
+
IRandom random = PRNG.Instance;
|
|
1357
|
+
|
|
1358
|
+
// Basic types
|
|
1359
|
+
int i = random.Next(); // int in [0, int.MaxValue]
|
|
1360
|
+
int range = random.Next(10, 20); // int in [10, 20)
|
|
1361
|
+
uint ui = random.NextUint(); // uint in [0, uint.MaxValue]
|
|
1362
|
+
float f = random.NextFloat(); // float in [0.0f, 1.0f]
|
|
1363
|
+
double d = random.NextDouble(); // double in [0.0d, 1.0d]
|
|
1364
|
+
bool b = random.NextBool(); // true or false
|
|
1365
|
+
|
|
1366
|
+
// Unity types
|
|
1367
|
+
Vector2 v2 = random.NextVector2(); // Random 2D vector
|
|
1368
|
+
Vector3 v3 = random.NextVector3(); // Random 3D vector
|
|
1369
|
+
Color color = random.NextColor(); // Random color
|
|
1370
|
+
Quaternion rot = random.NextRotation(); // Random rotation
|
|
1371
|
+
|
|
1372
|
+
// Distributions
|
|
1373
|
+
float gaussian = random.NextGaussian(mean: 0f, stdDev: 1f);
|
|
1374
|
+
float triangular = random.NextTriangular(min: 0f, max: 1f, mode: 0.5f);
|
|
1375
|
+
|
|
1376
|
+
// Collections
|
|
1377
|
+
T item = random.NextOf(collection); // Random element
|
|
1378
|
+
T[] shuffled = random.Shuffle(array); // Fisher-Yates shuffle
|
|
1379
|
+
int weightedIndex = random.NextWeightedIndex(weights);
|
|
1380
|
+
|
|
1381
|
+
// Special
|
|
1382
|
+
Guid uuid = random.NextGuid(); // UUIDv4
|
|
1383
|
+
T enumValue = random.NextEnum<T>(); // Random enum value
|
|
1384
|
+
float[,] noise = random.NextNoiseMap(width, height); // Perlin noise
|
|
1385
|
+
```
|
|
1386
|
+
|
|
1387
|
+
#### Deterministic Gameplay
|
|
1388
|
+
|
|
1389
|
+
All generators are **seedable** for replay systems:
|
|
1390
|
+
|
|
1391
|
+
```csharp
|
|
1392
|
+
// Create seeded generator for deterministic behavior
|
|
1393
|
+
IRandom seededRandom = new IllusionFlow(seed: 12345);
|
|
1394
|
+
|
|
1395
|
+
// Same seed = same sequence
|
|
1396
|
+
IRandom replay = new IllusionFlow(seed: 12345);
|
|
1397
|
+
// Both will generate identical values
|
|
1398
|
+
```
|
|
1399
|
+
|
|
1400
|
+
Threading
|
|
1401
|
+
|
|
1402
|
+
- Do not share a single RNG instance across threads.
|
|
1403
|
+
- Use `PRNG.Instance` for a thread-local default, or use each generator’s `TypeName.Instance` (e.g., `IllusionFlow.Instance`, `PcgRandom.Instance`).
|
|
1404
|
+
- Alternatively, create one separate instance per thread.
|
|
1405
|
+
|
|
1406
|
+
[📊 Performance Comparison](RANDOM_PERFORMANCE.md)
|
|
1407
|
+
|
|
1408
|
+
### Spatial Trees
|
|
1409
|
+
|
|
1410
|
+
Efficient spatial data structures for 2D and 3D games.
|
|
1411
|
+
|
|
1412
|
+
#### 2D Spatial Trees
|
|
1413
|
+
|
|
1414
|
+
- **QuadTree2D** - Best general-purpose choice
|
|
1415
|
+
- **KDTree2D** - Fast nearest-neighbor queries
|
|
1416
|
+
- **RTree2D** - Optimized for bounding boxes
|
|
1417
|
+
|
|
1418
|
+
```csharp
|
|
1419
|
+
using WallstopStudios.UnityHelpers.Core.DataStructure;
|
|
1420
|
+
|
|
1421
|
+
// Create from collection
|
|
1422
|
+
GameObject[] objects = FindObjectsOfType<GameObject>();
|
|
1423
|
+
QuadTree2D<GameObject> tree = new(objects, go => go.transform.position);
|
|
1424
|
+
|
|
1425
|
+
// Query by radius
|
|
1426
|
+
List<GameObject> nearby = new();
|
|
1427
|
+
tree.GetElementsInRange(playerPos, radius: 10f, nearby);
|
|
1428
|
+
|
|
1429
|
+
// Query by bounds
|
|
1430
|
+
Bounds searchArea = new(center, size);
|
|
1431
|
+
tree.GetElementsInBounds(searchArea, nearby);
|
|
1432
|
+
|
|
1433
|
+
// Find nearest neighbors (approximate, but fast)
|
|
1434
|
+
tree.GetApproximateNearestNeighbors(playerPos, count: 5, nearby);
|
|
1435
|
+
```
|
|
1436
|
+
|
|
1437
|
+
#### 3D Spatial Trees
|
|
1438
|
+
|
|
1439
|
+
Note: KdTree3D, OctTree3D, and RTree3D are under active development. SpatialHash3D is stable and production‑ready.
|
|
1440
|
+
|
|
1441
|
+
- **OctTree3D** - Best general-purpose choice for 3D
|
|
1442
|
+
- **KDTree3D** - Fast 3D nearest-neighbor queries
|
|
1443
|
+
- **RTree3D** - Optimized for 3D bounding volumes
|
|
1444
|
+
- **SpatialHash3D** - Efficient for uniformly distributed moving objects (stable)
|
|
1445
|
+
|
|
1446
|
+
```csharp
|
|
1447
|
+
// Same API as 2D, but with Vector3
|
|
1448
|
+
Vector3[] positions = GetAllPositions();
|
|
1449
|
+
OctTree3D<Vector3> tree = new(positions, p => p);
|
|
1450
|
+
|
|
1451
|
+
List<Vector3> results = new();
|
|
1452
|
+
tree.GetElementsInRange(center, radius: 50f, results);
|
|
1453
|
+
```
|
|
1454
|
+
|
|
1455
|
+
#### When to Use Spatial Trees
|
|
1456
|
+
|
|
1457
|
+
✅ **Good for:**
|
|
1458
|
+
|
|
1459
|
+
- Many objects (100+)
|
|
1460
|
+
- Frequent spatial queries
|
|
1461
|
+
- Static or slowly changing data
|
|
1462
|
+
- AI awareness systems
|
|
1463
|
+
- Visibility culling
|
|
1464
|
+
- Collision detection optimization
|
|
1465
|
+
|
|
1466
|
+
❌ **Not ideal for:**
|
|
1467
|
+
|
|
1468
|
+
- Few objects (<50)
|
|
1469
|
+
- Constantly moving objects
|
|
1470
|
+
- Single queries
|
|
1471
|
+
- Already using Unity's physics system
|
|
1472
|
+
|
|
1473
|
+
[📊 2D Benchmarks](SPATIAL_TREE_2D_PERFORMANCE.md) | [📊 3D Benchmarks](SPATIAL_TREE_3D_PERFORMANCE.md)
|
|
1474
|
+
|
|
1475
|
+
For behavior details and edge cases, see: [Spatial Tree Semantics](SPATIAL_TREE_SEMANTICS.md)
|
|
1476
|
+
|
|
1477
|
+
### Effects, Attributes, and Tags
|
|
1478
|
+
|
|
1479
|
+
Create data-driven gameplay effects that modify stats, apply tags, and drive cosmetics.
|
|
1480
|
+
|
|
1481
|
+
Key pieces:
|
|
1482
|
+
|
|
1483
|
+
- `AttributeEffect` — ScriptableObject that bundles stat changes, tags, cosmetics, and duration.
|
|
1484
|
+
- `EffectHandle` — Unique ID for one application instance; remove/refresh specific stacks.
|
|
1485
|
+
- `AttributesComponent` — Base class for components that expose modifiable `Attribute` fields.
|
|
1486
|
+
- `TagHandler` — Counts and queries string tags for gating gameplay (e.g., "Stunned").
|
|
1487
|
+
- `CosmeticEffectData` — Prefab-like container of behaviors shown while an effect is active.
|
|
1488
|
+
|
|
1489
|
+
Why this helps:
|
|
1490
|
+
|
|
1491
|
+
- Decouples gameplay logic from presentation and from effect sources.
|
|
1492
|
+
- Safe stacking and independent removal via handles and tag reference counts.
|
|
1493
|
+
- Designer-friendly: author once in assets, reuse everywhere.
|
|
1494
|
+
|
|
1495
|
+
Quick start:
|
|
1496
|
+
|
|
1497
|
+
```csharp
|
|
1498
|
+
using WallstopStudios.UnityHelpers.Tags;
|
|
1499
|
+
|
|
1500
|
+
// 1) Define stats on a component
|
|
1501
|
+
public class CharacterStats : AttributesComponent
|
|
1502
|
+
{
|
|
1503
|
+
public Attribute Health = 100f;
|
|
1504
|
+
public Attribute Speed = 5f;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
// 2) Author an AttributeEffect (ScriptableObject) in the editor
|
|
1508
|
+
// - modifications: [ { attribute: "Speed", action: Multiplication, value: 1.5f } ]
|
|
1509
|
+
// - durationType: Duration, duration: 5
|
|
1510
|
+
// - effectTags: [ "Haste" ]
|
|
1511
|
+
// - cosmeticEffects: [ a prefab with CosmeticEffectData + Particle/Audio components ]
|
|
1512
|
+
|
|
1513
|
+
// 3) Apply and later remove
|
|
1514
|
+
GameObject player = ...;
|
|
1515
|
+
AttributeEffect haste = ...; // ScriptableObject reference
|
|
1516
|
+
EffectHandle? handle = player.ApplyEffect(haste);
|
|
1517
|
+
if (handle.HasValue)
|
|
1518
|
+
{
|
|
1519
|
+
// Remove early if needed
|
|
1520
|
+
player.RemoveEffect(handle.Value);
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
// Query tags anywhere
|
|
1524
|
+
if (player.HasTag("Stunned")) { /* disable input */ }
|
|
1525
|
+
```
|
|
1526
|
+
|
|
1527
|
+
Details at a glance:
|
|
1528
|
+
|
|
1529
|
+
- `ModifierDurationType.Instant` — applies permanently; returns null handle.
|
|
1530
|
+
- `ModifierDurationType.Duration` — temporary; expires automatically; reapply can reset if enabled.
|
|
1531
|
+
- `ModifierDurationType.Infinite` — persists until `RemoveEffect(handle)` is called.
|
|
1532
|
+
- `AttributeModification` order: Addition → Multiplication → Override.
|
|
1533
|
+
- `CosmeticEffectData.RequiresInstancing` — instance per application or reuse shared presenters.
|
|
1534
|
+
|
|
1535
|
+
Tips:
|
|
1536
|
+
|
|
1537
|
+
- Use the Attribute Metadata Cache generator to power dropdowns and avoid typos in attribute names.
|
|
1538
|
+
- Prefer `%`-style changes with Multiplication and small flat changes with Addition.
|
|
1539
|
+
- Keep tag strings consistent; centralize in constants to avoid mistakes.
|
|
1540
|
+
|
|
1541
|
+
Further reading: see the full guide [Effects System](EFFECTS_SYSTEM.md).
|
|
1542
|
+
|
|
1543
|
+
### Component Attributes
|
|
1544
|
+
|
|
1545
|
+
Streamline component relationships and inspector validation.
|
|
1546
|
+
|
|
1547
|
+
#### Relational Component Attributes
|
|
1548
|
+
|
|
1549
|
+
```csharp
|
|
1550
|
+
public class Enemy : MonoBehaviour
|
|
1551
|
+
{
|
|
1552
|
+
// Find on same GameObject
|
|
1553
|
+
[SiblingComponent]
|
|
1554
|
+
private Animator animator;
|
|
1555
|
+
|
|
1556
|
+
// Find in parent
|
|
1557
|
+
[ParentComponent]
|
|
1558
|
+
private EnemySpawner spawner;
|
|
1559
|
+
|
|
1560
|
+
// Find in children
|
|
1561
|
+
[ChildComponent]
|
|
1562
|
+
private List<Weapon> weapons;
|
|
1563
|
+
|
|
1564
|
+
// Optional component (no error if missing)
|
|
1565
|
+
[SiblingComponent(Optional = true)]
|
|
1566
|
+
private AudioSource audioSource;
|
|
1567
|
+
|
|
1568
|
+
// Only search direct children/parents
|
|
1569
|
+
[ParentComponent(OnlyAncestors = true)]
|
|
1570
|
+
private Transform[] parentHierarchy;
|
|
1571
|
+
|
|
1572
|
+
// Include inactive components
|
|
1573
|
+
[ChildComponent(IncludeInactive = true)]
|
|
1574
|
+
private ParticleSystem[] effects;
|
|
1575
|
+
|
|
1576
|
+
private void Awake()
|
|
1577
|
+
{
|
|
1578
|
+
this.AssignRelationalComponents();
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
```
|
|
1582
|
+
|
|
1583
|
+
#### Validation Attributes
|
|
1584
|
+
|
|
1585
|
+
```csharp
|
|
1586
|
+
public class PlayerController : MonoBehaviour
|
|
1587
|
+
{
|
|
1588
|
+
// Validates at edit time, shows errors in inspector
|
|
1589
|
+
[ValidateAssignment]
|
|
1590
|
+
[SerializeField] private Rigidbody2D rigidbody;
|
|
1591
|
+
|
|
1592
|
+
// Must be assigned in inspector
|
|
1593
|
+
[NotNull]
|
|
1594
|
+
[SerializeField] private PlayerData playerData;
|
|
1595
|
+
|
|
1596
|
+
// Read-only display in inspector
|
|
1597
|
+
[DxReadOnly]
|
|
1598
|
+
public float currentHealth;
|
|
1599
|
+
|
|
1600
|
+
// Conditional display based on enum
|
|
1601
|
+
public enum Mode { Simple, Advanced }
|
|
1602
|
+
public Mode currentMode;
|
|
1603
|
+
|
|
1604
|
+
[WShowIf(nameof(currentMode), expectedValues = new object[] { Mode.Advanced })]
|
|
1605
|
+
public float advancedParameter;
|
|
1606
|
+
}
|
|
1607
|
+
```
|
|
1608
|
+
|
|
1609
|
+
### Serialization
|
|
1610
|
+
|
|
1611
|
+
[Full guide: Serialization](SERIALIZATION.md)
|
|
1612
|
+
|
|
1613
|
+
Fast, compact serialization for save systems, config, and networking.
|
|
1614
|
+
|
|
1615
|
+
This package provides three serialization technologies:
|
|
1616
|
+
|
|
1617
|
+
- `Json` — Uses System.Text.Json with built‑in converters for Unity types.
|
|
1618
|
+
- `Protobuf` — Uses protobuf-net for compact, fast, schema‑evolvable binary.
|
|
1619
|
+
- `SystemBinary` — Uses .NET BinaryFormatter for legacy/ephemeral data only.
|
|
1620
|
+
|
|
1621
|
+
All are exposed via `WallstopStudios.UnityHelpers.Core.Serialization.Serializer`.
|
|
1622
|
+
|
|
1623
|
+
#### Formats Provided
|
|
1624
|
+
|
|
1625
|
+
- Json
|
|
1626
|
+
- Human‑readable; great for configs, save files you want to inspect or diff.
|
|
1627
|
+
- Includes converters for Unity types (Vector2/3/4, Color, Matrix4x4, GameObject, Type, enums as strings, cycles ignored, case‑insensitive, includes fields).
|
|
1628
|
+
- Protobuf (protobuf‑net)
|
|
1629
|
+
- Small, fast, ideal for networking and large save payloads.
|
|
1630
|
+
- Forward/backward compatible when evolving messages (see tips below).
|
|
1631
|
+
- SystemBinary (BinaryFormatter)
|
|
1632
|
+
- Only for legacy or trusted, same‑version, local data. Not recommended for long‑term persistence or untrusted input (security + versioning issues).
|
|
1633
|
+
|
|
1634
|
+
#### When To Use What
|
|
1635
|
+
|
|
1636
|
+
- Use Json for:
|
|
1637
|
+
- Player or tool settings, human‑readable saves, serverless workflows.
|
|
1638
|
+
- Interop with tooling, debugging, or versioning in Git.
|
|
1639
|
+
- Use Protobuf for:
|
|
1640
|
+
- Network payloads, large save files, bandwidth/storage‑sensitive data.
|
|
1641
|
+
- Situations where you expect schema evolution across versions.
|
|
1642
|
+
- Use SystemBinary only for:
|
|
1643
|
+
- Transient caches in trusted environments where data and code version match.
|
|
1644
|
+
- Never for untrusted data or long‑term persistence.
|
|
1645
|
+
|
|
1646
|
+
#### JSON Examples (Unity‑aware)
|
|
1647
|
+
|
|
1648
|
+
```csharp
|
|
1649
|
+
using System.Collections.Generic;
|
|
1650
|
+
using UnityEngine;
|
|
1651
|
+
using WallstopStudios.UnityHelpers.Core.Serialization;
|
|
1652
|
+
|
|
1653
|
+
public class SaveData
|
|
1654
|
+
{
|
|
1655
|
+
public Vector3 position;
|
|
1656
|
+
public Color playerColor;
|
|
1657
|
+
public List<GameObject> inventory;
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
var data = new SaveData
|
|
1661
|
+
{
|
|
1662
|
+
position = new Vector3(1, 2, 3),
|
|
1663
|
+
playerColor = Color.cyan,
|
|
1664
|
+
inventory = new List<GameObject>()
|
|
1665
|
+
};
|
|
1666
|
+
|
|
1667
|
+
// Serialize to UTF‑8 JSON bytes (Unity types supported via built‑in converters)
|
|
1668
|
+
byte[] jsonBytes = Serializer.JsonSerialize(data);
|
|
1669
|
+
|
|
1670
|
+
// Deserialize from string
|
|
1671
|
+
string jsonText = Serializer.JsonStringify(data, pretty: true);
|
|
1672
|
+
SaveData fromText = Serializer.JsonDeserialize<SaveData>(jsonText);
|
|
1673
|
+
|
|
1674
|
+
// File helpers
|
|
1675
|
+
Serializer.WriteToJsonFile(data, path: "save.json", pretty: true);
|
|
1676
|
+
SaveData fromFile = Serializer.ReadFromJsonFile<SaveData>("save.json");
|
|
1677
|
+
|
|
1678
|
+
// Generic entry points (choose format at runtime)
|
|
1679
|
+
byte[] bytes = Serializer.Serialize(data, SerializationType.Json);
|
|
1680
|
+
SaveData loaded = Serializer.Deserialize<SaveData>(bytes, SerializationType.Json);
|
|
1681
|
+
```
|
|
1682
|
+
|
|
1683
|
+
#### Protobuf Examples (Compact + Evolvable)
|
|
1684
|
+
|
|
1685
|
+
```csharp
|
|
1686
|
+
using ProtoBuf; // protobuf-net
|
|
1687
|
+
using UnityEngine;
|
|
1688
|
+
using WallstopStudios.UnityHelpers.Core.Serialization;
|
|
1689
|
+
|
|
1690
|
+
[ProtoContract]
|
|
1691
|
+
public class NetworkMessage
|
|
1692
|
+
{
|
|
1693
|
+
[ProtoMember(1)] public int playerId;
|
|
1694
|
+
[ProtoMember(2)] public Vector3 position; // Vector3 works in Protobuf via built-in surrogates
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
var message = new NetworkMessage { playerId = 7, position = new Vector3(5, 0, -2) };
|
|
1698
|
+
|
|
1699
|
+
// Protobuf bytes (small + fast)
|
|
1700
|
+
byte[] bytes = Serializer.ProtoSerialize(message);
|
|
1701
|
+
NetworkMessage decoded = Serializer.ProtoDeserialize<NetworkMessage>(bytes);
|
|
1702
|
+
|
|
1703
|
+
// Generic entry points
|
|
1704
|
+
byte[] bytes2 = Serializer.Serialize(message, SerializationType.Protobuf);
|
|
1705
|
+
NetworkMessage decoded2 = Serializer.Deserialize<NetworkMessage>(bytes2, SerializationType.Protobuf);
|
|
1706
|
+
|
|
1707
|
+
// Buffer reuse (reduce GC for hot paths)
|
|
1708
|
+
byte[] buffer = null;
|
|
1709
|
+
int len = Serializer.Serialize(message, SerializationType.Protobuf, ref buffer);
|
|
1710
|
+
NetworkMessage again = Serializer.Deserialize<NetworkMessage>(buffer.AsSpan(0, len).ToArray(), SerializationType.Protobuf);
|
|
1711
|
+
```
|
|
1712
|
+
|
|
1713
|
+
Notes:
|
|
1714
|
+
|
|
1715
|
+
- Protobuf‑net requires stable field numbers. Annotate with `[ProtoMember(n)]` and never reuse or renumber.
|
|
1716
|
+
- Unity types supported via surrogates: Vector2/3, Vector2Int/3Int, Quaternion, Color/Color32, Rect/RectInt, Bounds/BoundsInt, Resolution.
|
|
1717
|
+
|
|
1718
|
+
#### Protobuf Compatibility Tips
|
|
1719
|
+
|
|
1720
|
+
- Add fields with new numbers; old clients ignore unknown fields, new clients default missing fields.
|
|
1721
|
+
- Do not change field numbers or `oneof` layout; reserve removed numbers if needed.
|
|
1722
|
+
- Avoid switching scalar types (e.g., `int32` → `string`) on the same number.
|
|
1723
|
+
- Prefer optional/repeated over required; required breaks backward compatibility.
|
|
1724
|
+
- Use sensible defaults to keep payloads minimal.
|
|
1725
|
+
|
|
1726
|
+
#### SystemBinary Examples (Legacy/Trusted Only)
|
|
1727
|
+
|
|
1728
|
+
```csharp
|
|
1729
|
+
using WallstopStudios.UnityHelpers.Core.Serialization;
|
|
1730
|
+
|
|
1731
|
+
var obj = new SomeSerializableType();
|
|
1732
|
+
byte[] bin = Serializer.BinarySerialize(obj);
|
|
1733
|
+
SomeSerializableType roundtrip = Serializer.BinaryDeserialize<SomeSerializableType>(bin);
|
|
1734
|
+
|
|
1735
|
+
// Generic
|
|
1736
|
+
byte[] bin2 = Serializer.Serialize(obj, SerializationType.SystemBinary);
|
|
1737
|
+
var round2 = Serializer.Deserialize<SomeSerializableType>(bin2, SerializationType.SystemBinary);
|
|
1738
|
+
```
|
|
1739
|
+
|
|
1740
|
+
Watch‑outs:
|
|
1741
|
+
|
|
1742
|
+
- BinaryFormatter is obsolete in modern .NET and not secure for untrusted input.
|
|
1743
|
+
- Version changes often break binary round‑trips; use only for same‑version caches.
|
|
1744
|
+
|
|
1745
|
+
**Features:**
|
|
1746
|
+
|
|
1747
|
+
- Custom converters for Unity types (Vector2/3/4, Color, GameObject, Matrix4x4, Type)
|
|
1748
|
+
- Protobuf (protobuf‑net) support for compact binary
|
|
1749
|
+
- LZMA compression utilities (see `Runtime/Utils/LZMA.cs`)
|
|
1750
|
+
- Type‑safe serialization and pooled buffers/writers to reduce GC
|
|
1751
|
+
|
|
1752
|
+
### Data Structures
|
|
1753
|
+
|
|
1754
|
+
Additional high-performance data structures:
|
|
1755
|
+
|
|
1756
|
+
| Structure | Use Case |
|
|
1757
|
+
| -------------------- | ------------------------------ |
|
|
1758
|
+
| **CyclicBuffer<T>** | Ring buffer, sliding windows |
|
|
1759
|
+
| **BitSet** | Compact boolean storage |
|
|
1760
|
+
| **ImmutableBitSet** | Read-only bit flags |
|
|
1761
|
+
| **Heap<T>** | Priority queue operations |
|
|
1762
|
+
| **PriorityQueue<T>** | Event scheduling |
|
|
1763
|
+
| **Deque<T>** | Double-ended queue |
|
|
1764
|
+
| **DisjointSet** | Union-find operations |
|
|
1765
|
+
| **Trie** | String prefix trees |
|
|
1766
|
+
| **SparseSet** | Fast add/remove with iteration |
|
|
1767
|
+
| **TimedCache<T>** | Auto-expiring cache |
|
|
1768
|
+
|
|
1769
|
+
```csharp
|
|
1770
|
+
// Cyclic buffer for damage history
|
|
1771
|
+
CyclicBuffer<float> damageHistory = new(capacity: 10);
|
|
1772
|
+
damageHistory.Add(25f);
|
|
1773
|
+
damageHistory.Add(30f);
|
|
1774
|
+
float avgDamage = damageHistory.Average();
|
|
1775
|
+
|
|
1776
|
+
// Priority queue for event scheduling
|
|
1777
|
+
PriorityQueue<GameEvent> eventQueue = new();
|
|
1778
|
+
eventQueue.Enqueue(spawnEvent, priority: 1);
|
|
1779
|
+
eventQueue.Enqueue(bossEvent, priority: 10);
|
|
1780
|
+
GameEvent next = eventQueue.Dequeue(); // Highest priority
|
|
1781
|
+
|
|
1782
|
+
// Trie for autocomplete
|
|
1783
|
+
Trie commandTrie = new();
|
|
1784
|
+
commandTrie.Insert("teleport");
|
|
1785
|
+
commandTrie.Insert("tell");
|
|
1786
|
+
commandTrie.Insert("terrain");
|
|
1787
|
+
List<string> matches = commandTrie.GetWordsWithPrefix("tel");
|
|
1788
|
+
// Returns: ["teleport", "tell"]
|
|
1789
|
+
```
|
|
1790
|
+
|
|
1791
|
+
### Helpers & Extensions
|
|
1792
|
+
|
|
1793
|
+
See also: [Buffering Pattern](#buffering-pattern)
|
|
1794
|
+
|
|
1795
|
+
High-level helpers and extension methods that streamline day-to-day Unity work.
|
|
1796
|
+
|
|
1797
|
+
#### Context-Aware Logging with Custom Formatters
|
|
1798
|
+
|
|
1799
|
+
Unity Helpers includes a powerful logging system with automatic context injection, custom formatters, and build-time stripping:
|
|
1800
|
+
|
|
1801
|
+
**Key Features:**
|
|
1802
|
+
|
|
1803
|
+
- **Automatic Context & Timing** — Every log includes GameObject name, component type, and timestamp
|
|
1804
|
+
- **Exception Overloads** — Pass exceptions directly: `this.LogError($"Failed to load {asset}", exception)`
|
|
1805
|
+
- **Custom Formatters** — Built-in support for colors, bold, italic, JSON, sizing, and extensible with your own
|
|
1806
|
+
- **Thread-Safe** — Automatically routes logs to Unity main thread when needed
|
|
1807
|
+
- **Build Stripping** — Controlled via scripting defines (`ENABLE_UBERLOGGING`, `DEBUG_LOGGING`, etc.)
|
|
1808
|
+
- **Per-Object Control** — Enable/disable logging globally or per-component
|
|
1809
|
+
|
|
1810
|
+
**Quick Example:**
|
|
1811
|
+
|
|
1812
|
+
```csharp
|
|
1813
|
+
using WallstopStudios.UnityHelpers.Core.Extension;
|
|
1814
|
+
|
|
1815
|
+
public class PlayerController : MonoBehaviour
|
|
1816
|
+
{
|
|
1817
|
+
void Start()
|
|
1818
|
+
{
|
|
1819
|
+
// Simple logging with automatic context
|
|
1820
|
+
this.Log($"Player initialized");
|
|
1821
|
+
// Output: 12.34|PlayerController[PlayerController]|Player initialized
|
|
1822
|
+
|
|
1823
|
+
// Rich formatting with colors and bold
|
|
1824
|
+
int health = 100;
|
|
1825
|
+
this.Log($"Health: {"100":b,#green}");
|
|
1826
|
+
// Output (in Unity): 12.34|PlayerController[PlayerController]|Health: <b><color=#00FF00FF>100</color></b>
|
|
1827
|
+
|
|
1828
|
+
// JSON serialization
|
|
1829
|
+
var data = new { x = 10, y = 20 };
|
|
1830
|
+
this.LogWarn($"Position data: {data:json}");
|
|
1831
|
+
// Output: 12.34|PlayerController[PlayerController]|Position data: {"x":10,"y":20}
|
|
1832
|
+
|
|
1833
|
+
// Exception logging
|
|
1834
|
+
try
|
|
1835
|
+
{
|
|
1836
|
+
// ... risky operation
|
|
1837
|
+
}
|
|
1838
|
+
catch (Exception e)
|
|
1839
|
+
{
|
|
1840
|
+
this.LogError($"Failed to save game", e);
|
|
1841
|
+
// Includes full exception with stack trace
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
```
|
|
1846
|
+
|
|
1847
|
+
**Supported Format Tags:**
|
|
1848
|
+
|
|
1849
|
+
- `b`, `bold`, `!` — **Bold text** (editor only)
|
|
1850
|
+
- `i`, `italic`, `_` — _Italic text_ (editor only)
|
|
1851
|
+
- `#colorName` or `#RRGGBB` — <span style="color:red">Colored text</span> (editor only)
|
|
1852
|
+
- `json` — JSON serialization (works everywhere)
|
|
1853
|
+
- `12` or `size=12` — Sized text 1-100 (editor only)
|
|
1854
|
+
- Stack multiple: `{value:b,#red,20}` → large, bold, red text
|
|
1855
|
+
|
|
1856
|
+
**Custom Formatters:**
|
|
1857
|
+
|
|
1858
|
+
```csharp
|
|
1859
|
+
using WallstopStudios.UnityHelpers.Core.Helper.Logging;
|
|
1860
|
+
|
|
1861
|
+
// Add your own formatter
|
|
1862
|
+
UnityLogTagFormatter formatter = WallstopStudiosLogger.LogInstance;
|
|
1863
|
+
formatter.AddDecoration(
|
|
1864
|
+
match: "upper",
|
|
1865
|
+
format: value => value.ToString().ToUpper(),
|
|
1866
|
+
tag: "Uppercase"
|
|
1867
|
+
);
|
|
1868
|
+
|
|
1869
|
+
// Use it
|
|
1870
|
+
this.Log($"{"hello":upper}"); // Output: HELLO
|
|
1871
|
+
```
|
|
1872
|
+
|
|
1873
|
+
**Build-Time Control:**
|
|
1874
|
+
|
|
1875
|
+
```csharp
|
|
1876
|
+
// Logs are enabled by default in:
|
|
1877
|
+
// - Development builds (DEVELOPMENT_BUILD)
|
|
1878
|
+
// - Debug builds (DEBUG)
|
|
1879
|
+
// - Unity Editor (UNITY_EDITOR)
|
|
1880
|
+
|
|
1881
|
+
// Override with scripting defines:
|
|
1882
|
+
// ENABLE_UBERLOGGING - Enable all logs
|
|
1883
|
+
// DEBUG_LOGGING - Enable Log() calls only
|
|
1884
|
+
// WARN_LOGGING - Enable LogWarn() calls only
|
|
1885
|
+
// ERROR_LOGGING - Enable LogError() calls only
|
|
1886
|
+
|
|
1887
|
+
// Runtime control
|
|
1888
|
+
this.DisableLogging(); // Disable logs for this component
|
|
1889
|
+
this.EnableLogging(); // Re-enable logs for this component
|
|
1890
|
+
this.GlobalDisableLogging(); // Disable all logs
|
|
1891
|
+
this.GlobalEnableLogging(); // Re-enable all logs
|
|
1892
|
+
```
|
|
1893
|
+
|
|
1894
|
+
**Other Key Helpers:**
|
|
1895
|
+
|
|
1896
|
+
- `Helpers.Find<T>(tag)` and `HasComponent<T>()` — Fewer `GetComponent` calls, cached lookups by tag.
|
|
1897
|
+
- `GetOrAddComponent<T>()` — Idempotent component setup in initialization code.
|
|
1898
|
+
- `DestroyAllChildren*` and `SmartDestroy()` — Safe destroy patterns across editor/runtime.
|
|
1899
|
+
- `StartFunctionAsCoroutine(action, rate, useJitter)` — Simple polling/ticking utilities.
|
|
1900
|
+
- `UpdateShapeToSprite()` — Sync `PolygonCollider2D` to `SpriteRenderer` at runtime.
|
|
1901
|
+
- `GetAllLayerNames()` and `GetAllSpriteLabelNames()` — Editor integrations and tooling.
|
|
1902
|
+
- `GetRandomPointInCircle/Sphere()` — Uniform random positions for spawn/FX.
|
|
1903
|
+
- Unity Extensions: conversions (`Rect`⇄`Bounds`), camera `OrthographicBounds()`, physics `Rigidbody2D.Stop()`, input filtering `Vector2.IsNoise()`.
|
|
1904
|
+
|
|
1905
|
+
Examples:
|
|
1906
|
+
|
|
1907
|
+
```csharp
|
|
1908
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
1909
|
+
using WallstopStudios.UnityHelpers.Core.Extension;
|
|
1910
|
+
using UnityEngine;
|
|
1911
|
+
|
|
1912
|
+
public class Setup : MonoBehaviour
|
|
1913
|
+
{
|
|
1914
|
+
void Awake()
|
|
1915
|
+
{
|
|
1916
|
+
// Component orchestration
|
|
1917
|
+
var rb = gameObject.GetOrAddComponent<Rigidbody2D>();
|
|
1918
|
+
if (gameObject.HasComponent<SpriteRenderer>())
|
|
1919
|
+
{
|
|
1920
|
+
// Match collider to current sprite at runtime
|
|
1921
|
+
gameObject.UpdateShapeToSprite();
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
// Destroy patterns
|
|
1925
|
+
transform.parent.gameObject.DestroyAllChildrenGameObjects(); // runtime-safe
|
|
1926
|
+
|
|
1927
|
+
// Lightweight polling
|
|
1928
|
+
this.StartFunctionAsCoroutine(() => Debug.Log("Tick"), 0.5f, useJitter: true);
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
public class CameraUtils : MonoBehaviour
|
|
1933
|
+
{
|
|
1934
|
+
void OnDrawGizmosSelected()
|
|
1935
|
+
{
|
|
1936
|
+
if (Camera.main)
|
|
1937
|
+
{
|
|
1938
|
+
// Compute world-space orthographic bounds for culling or UI logic
|
|
1939
|
+
Bounds view = Camera.main.OrthographicBounds();
|
|
1940
|
+
Gizmos.DrawWireCube(view.center, view.size);
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
```
|
|
1945
|
+
|
|
1946
|
+
When to use what:
|
|
1947
|
+
|
|
1948
|
+
- Prefer `SpatialHash2D` for many moving objects uniformly spread; prefer `QuadTree2D` for static or semi-static content with clustered queries.
|
|
1949
|
+
- Use `Helpers.StartFunctionAsCoroutine` for simple, frame-safe polling; prefer `InvokeRepeating` or custom `Update` loops when you need fine-grained frame ordering.
|
|
1950
|
+
- Use `SmartDestroy` when writing code that runs in both edit mode and play mode to avoid editor/runtime differences.
|
|
1951
|
+
|
|
1952
|
+
### Choosing Helpers
|
|
1953
|
+
|
|
1954
|
+
- Destroy patterns: Use `SmartDestroy` for editor/play safe teardown; `DestroyAllChildren*` to clear hierarchies quickly.
|
|
1955
|
+
- Component wiring: Prefer relational attributes (`[SiblingComponent]`, etc.) + `AssignRelationalComponents()` over manual `GetComponent` calls.
|
|
1956
|
+
- To avoid first-use reflection overhead, prewarm caches at startup with `RelationalComponentInitializer.Initialize()` or enable “Prewarm Relational On Load” on the AttributeMetadataCache asset.
|
|
1957
|
+
- Random placement: Use `Helpers.GetRandomPointInCircle/Sphere` or `RandomExtensions.NextVector2/3(InRange)` for uniform distributions.
|
|
1958
|
+
- Asset/tooling: `GetAllLayerNames` and `GetAllSpriteLabelNames` power menu tooling and editor workflows.
|
|
1959
|
+
- Math/geometry: `WallMath.PositiveMod/Wrapped*` for robust wrap-around; `LineHelper.Simplify*` to reduce polyline complexity; `Geometry.IsAPointLeftOfVectorOrOnTheLine` for sidedness tests.
|
|
1960
|
+
|
|
1961
|
+
### Editor Tools
|
|
1962
|
+
|
|
1963
|
+
Unity Helpers includes 20+ editor tools to streamline your workflow:
|
|
1964
|
+
|
|
1965
|
+
- **Sprite Tools**: Cropper, Atlas Generator, Animation Editor, Pivot Adjuster
|
|
1966
|
+
- **Texture Tools**: Blur, Resize, Settings Applier, Fit Texture Size
|
|
1967
|
+
- **Animation Tools**: Event Editor, Creator, Copier, Sheet Animation Creator
|
|
1968
|
+
- **Validation**: Prefab Checker with comprehensive validation rules
|
|
1969
|
+
- **Automation**: ScriptableObject Singleton Creator, Attribute Cache Generator
|
|
1970
|
+
|
|
1971
|
+
[📖 Complete Editor Tools Documentation](EDITOR_TOOLS_GUIDE.md)
|
|
1972
|
+
|
|
1973
|
+
**Quick Access:**
|
|
1974
|
+
|
|
1975
|
+
- Menu: `Tools > Wallstop Studios > Unity Helpers`
|
|
1976
|
+
- Create Assets: `Assets > Create > Wallstop Studios > Unity Helpers`
|
|
1977
|
+
|
|
1978
|
+
<a id="use-cases--examples"></a>
|
|
1979
|
+
<a id="use-cases-examples"></a>
|
|
1980
|
+
|
|
1981
|
+
## Use Cases & Examples
|
|
1982
|
+
|
|
1983
|
+
### Case Study: Player Controller with Auto-Wiring
|
|
1984
|
+
|
|
1985
|
+
Clean, maintainable character controllers using relational components to eliminate GetComponent boilerplate.
|
|
1986
|
+
|
|
1987
|
+
```csharp
|
|
1988
|
+
using UnityEngine;
|
|
1989
|
+
using WallstopStudios.UnityHelpers.Core.Attributes;
|
|
1990
|
+
|
|
1991
|
+
public class PlayerController : MonoBehaviour
|
|
1992
|
+
{
|
|
1993
|
+
// Auto-wire components - no GetComponent needed
|
|
1994
|
+
[SiblingComponent] private Rigidbody2D rb;
|
|
1995
|
+
[SiblingComponent] private SpriteRenderer spriteRenderer;
|
|
1996
|
+
[SiblingComponent] private Animator animator;
|
|
1997
|
+
[ChildComponent(OnlyDescendants = true)] private Collider2D[] hitboxes;
|
|
1998
|
+
|
|
1999
|
+
[Header("Stats")]
|
|
2000
|
+
public float moveSpeed = 5f;
|
|
2001
|
+
public float jumpForce = 10f;
|
|
2002
|
+
|
|
2003
|
+
void Awake()
|
|
2004
|
+
{
|
|
2005
|
+
// One call wires everything
|
|
2006
|
+
this.AssignRelationalComponents();
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
void Update()
|
|
2010
|
+
{
|
|
2011
|
+
// Movement
|
|
2012
|
+
float horizontal = Input.GetAxis("Horizontal");
|
|
2013
|
+
rb.velocity = new Vector2(horizontal * moveSpeed, rb.velocity.y);
|
|
2014
|
+
|
|
2015
|
+
// Flip sprite
|
|
2016
|
+
if (horizontal != 0)
|
|
2017
|
+
spriteRenderer.flipX = horizontal < 0;
|
|
2018
|
+
|
|
2019
|
+
// Animate
|
|
2020
|
+
animator.SetFloat("Speed", Mathf.Abs(horizontal));
|
|
2021
|
+
|
|
2022
|
+
// Jump
|
|
2023
|
+
if (Input.GetButtonDown("Jump") && IsGrounded())
|
|
2024
|
+
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
bool IsGrounded()
|
|
2028
|
+
{
|
|
2029
|
+
// Efficiently check all child colliders
|
|
2030
|
+
foreach (var hitbox in hitboxes)
|
|
2031
|
+
{
|
|
2032
|
+
if (hitbox.IsTouchingLayers(LayerMask.GetMask("Ground")))
|
|
2033
|
+
return true;
|
|
2034
|
+
}
|
|
2035
|
+
return false;
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
```
|
|
2039
|
+
|
|
2040
|
+
**Key benefits:**
|
|
2041
|
+
|
|
2042
|
+
- **Zero boilerplate:** No GetComponent calls, null checks, or error handling
|
|
2043
|
+
- **Self-documenting:** Clear intent with attributes (`[ChildComponent]`)
|
|
2044
|
+
- **Compile-time safety:** Typos caught immediately
|
|
2045
|
+
- **Scales beautifully:** Works for simple and complex hierarchies
|
|
2046
|
+
|
|
2047
|
+
---
|
|
2048
|
+
|
|
2049
|
+
### Case Study: Buff/Debuff System with Effects
|
|
2050
|
+
|
|
2051
|
+
Complete status effect system with zero code - everything configured in the editor.
|
|
2052
|
+
|
|
2053
|
+
```csharp
|
|
2054
|
+
using UnityEngine;
|
|
2055
|
+
using WallstopStudios.UnityHelpers.Tags;
|
|
2056
|
+
|
|
2057
|
+
// 1. Define stats that effects can modify
|
|
2058
|
+
public class CharacterStats : AttributesComponent
|
|
2059
|
+
{
|
|
2060
|
+
public Attribute Speed = 5f;
|
|
2061
|
+
public Attribute Damage = 10f;
|
|
2062
|
+
public Attribute Defense = 5f;
|
|
2063
|
+
public Attribute Health = 100f;
|
|
2064
|
+
}
|
|
2065
|
+
|
|
2066
|
+
// 2. Use in gameplay
|
|
2067
|
+
public class Character : MonoBehaviour
|
|
2068
|
+
{
|
|
2069
|
+
[SiblingComponent] private CharacterStats stats;
|
|
2070
|
+
|
|
2071
|
+
[Header("Effect Prefabs")]
|
|
2072
|
+
[SerializeField] private AttributeEffect hasteEffect; // Created in editor
|
|
2073
|
+
[SerializeField] private AttributeEffect shieldEffect; // Created in editor
|
|
2074
|
+
[SerializeField] private AttributeEffect stunEffect; // Created in editor
|
|
2075
|
+
|
|
2076
|
+
void Awake()
|
|
2077
|
+
{
|
|
2078
|
+
this.AssignRelationalComponents();
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
void Update()
|
|
2082
|
+
{
|
|
2083
|
+
// Check status via tags
|
|
2084
|
+
if (this.HasTag("Stunned"))
|
|
2085
|
+
{
|
|
2086
|
+
Debug.Log("Can't act while stunned!");
|
|
2087
|
+
return;
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
// Normal gameplay using dynamic stats
|
|
2091
|
+
float currentSpeed = stats.Speed.Value; // Respects all active buffs/debuffs
|
|
2092
|
+
transform.position += Vector3.right * currentSpeed * Time.deltaTime;
|
|
2093
|
+
|
|
2094
|
+
// Combat
|
|
2095
|
+
if (this.HasTag("Invulnerable"))
|
|
2096
|
+
return; // Immune to damage
|
|
2097
|
+
|
|
2098
|
+
// Apply damage with defense calculation
|
|
2099
|
+
float incomingDamage = 20f;
|
|
2100
|
+
float actualDamage = Mathf.Max(0, incomingDamage - stats.Defense.Value);
|
|
2101
|
+
stats.Health.Value -= actualDamage;
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
// Apply effects from other systems (items, abilities, enemies)
|
|
2105
|
+
public void ApplyBuff(AttributeEffect effect)
|
|
2106
|
+
{
|
|
2107
|
+
this.ApplyEffect(effect);
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
public void Cleanse()
|
|
2111
|
+
{
|
|
2112
|
+
// Remove all debuffs at once
|
|
2113
|
+
this.RemoveAllEffectsWithTag("Debuff");
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
```
|
|
2117
|
+
|
|
2118
|
+
**In the Unity Editor, create AttributeEffect ScriptableObjects:**
|
|
2119
|
+
|
|
2120
|
+
**HasteEffect.asset:**
|
|
2121
|
+
|
|
2122
|
+
- Modifications: Speed × 1.5
|
|
2123
|
+
- Duration: 5 seconds
|
|
2124
|
+
- Tags: "Haste", "Buff"
|
|
2125
|
+
- Visual: Speed lines particle effect
|
|
2126
|
+
|
|
2127
|
+
**ShieldEffect.asset:**
|
|
2128
|
+
|
|
2129
|
+
- Modifications: Defense + 10
|
|
2130
|
+
- Duration: 10 seconds
|
|
2131
|
+
- Tags: "Shield", "Buff"
|
|
2132
|
+
- Grant Tags: "Invulnerable"
|
|
2133
|
+
- Visual: Blue shield glow
|
|
2134
|
+
|
|
2135
|
+
**StunEffect.asset:**
|
|
2136
|
+
|
|
2137
|
+
- Modifications: Speed = 0 (Override)
|
|
2138
|
+
- Duration: 3 seconds
|
|
2139
|
+
- Tags: "Stun", "Debuff", "CC"
|
|
2140
|
+
- Grant Tags: "Stunned"
|
|
2141
|
+
- Visual: Stars circling head
|
|
2142
|
+
|
|
2143
|
+
**Why this is game-changing:**
|
|
2144
|
+
|
|
2145
|
+
- **Zero effect code:** Designers create hundreds of effects without programmer involvement
|
|
2146
|
+
- **Instant prototyping:** New buff in 30 seconds (create ScriptableObject, set values)
|
|
2147
|
+
- **Perfect stacking:** Multiple effects work together automatically
|
|
2148
|
+
- **Visual polish:** Particles spawn/despawn with effects
|
|
2149
|
+
- **Gameplay queries:** Check tags for immunity, crowd control, etc.
|
|
2150
|
+
|
|
2151
|
+
**Tutorial:** See [Effects System Tutorial](EFFECTS_SYSTEM_TUTORIAL.md) for step-by-step guide.
|
|
2152
|
+
|
|
2153
|
+
---
|
|
2154
|
+
|
|
2155
|
+
### Case Study: Loot System with Weighted Random
|
|
2156
|
+
|
|
2157
|
+
Robust loot drops using Unity Helpers' extensive random API - no manual weight calculations.
|
|
2158
|
+
|
|
2159
|
+
```csharp
|
|
2160
|
+
using UnityEngine;
|
|
2161
|
+
using WallstopStudios.UnityHelpers.Core.Random;
|
|
2162
|
+
using WallstopStudios.UnityHelpers.Core.Extension;
|
|
2163
|
+
|
|
2164
|
+
public class LootTable : MonoBehaviour
|
|
2165
|
+
{
|
|
2166
|
+
private IRandom random = PRNG.Instance;
|
|
2167
|
+
|
|
2168
|
+
[System.Serializable]
|
|
2169
|
+
public class LootEntry
|
|
2170
|
+
{
|
|
2171
|
+
public GameObject itemPrefab;
|
|
2172
|
+
public float dropChance; // 0.0 to 1.0
|
|
2173
|
+
public int minCount;
|
|
2174
|
+
public int maxCount;
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
public List<LootEntry> lootEntries;
|
|
2178
|
+
|
|
2179
|
+
public List<GameObject> RollLoot()
|
|
2180
|
+
{
|
|
2181
|
+
List<GameObject> rewards = new();
|
|
2182
|
+
|
|
2183
|
+
// Simple weighted selection
|
|
2184
|
+
float[] weights = lootEntries.Select(e => e.dropChance).ToArray();
|
|
2185
|
+
int rolledIndex = random.NextWeightedIndex(weights);
|
|
2186
|
+
|
|
2187
|
+
LootEntry winner = lootEntries[rolledIndex];
|
|
2188
|
+
int count = random.Next(winner.minCount, winner.maxCount + 1);
|
|
2189
|
+
|
|
2190
|
+
for (int i = 0; i < count; i++)
|
|
2191
|
+
rewards.Add(winner.itemPrefab);
|
|
2192
|
+
|
|
2193
|
+
return rewards;
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
public GameObject RollRareItem()
|
|
2197
|
+
{
|
|
2198
|
+
// Weighted bool for rare drops (20% chance)
|
|
2199
|
+
if (random.NextBool(probability: 0.2f))
|
|
2200
|
+
{
|
|
2201
|
+
// Select from rare items only
|
|
2202
|
+
var rareItems = lootEntries.Where(e => e.dropChance < 0.1f).ToArray();
|
|
2203
|
+
return random.NextOf(rareItems).itemPrefab;
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
return null;
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
public List<GameObject> RollMultipleItems(int rollCount)
|
|
2210
|
+
{
|
|
2211
|
+
List<GameObject> rewards = new();
|
|
2212
|
+
|
|
2213
|
+
// Each entry can drop independently
|
|
2214
|
+
foreach (var entry in lootEntries)
|
|
2215
|
+
{
|
|
2216
|
+
if (random.NextFloat() < entry.dropChance)
|
|
2217
|
+
{
|
|
2218
|
+
int count = random.Next(entry.minCount, entry.maxCount + 1);
|
|
2219
|
+
for (int i = 0; i < count; i++)
|
|
2220
|
+
rewards.Add(entry.itemPrefab);
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
// Shuffle for variety
|
|
2225
|
+
return random.Shuffle(rewards).ToList();
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
```
|
|
2229
|
+
|
|
2230
|
+
**Why Unity Helpers' random API shines here:**
|
|
2231
|
+
|
|
2232
|
+
- **NextWeightedIndex():** Handles normalization automatically
|
|
2233
|
+
- **NextBool(probability):** Cleaner than `NextFloat() < 0.2f`
|
|
2234
|
+
- **NextOf(array):** Direct selection without manual indexing
|
|
2235
|
+
- **Shuffle():** Built-in for random order
|
|
2236
|
+
- **10-15x faster** than UnityEngine.Random
|
|
2237
|
+
|
|
2238
|
+
---
|
|
2239
|
+
|
|
2240
|
+
### Case Study: Procedural Level Generation
|
|
2241
|
+
|
|
2242
|
+
Deterministic terrain using Perlin noise, Gaussian distributions, and seeded random.
|
|
2243
|
+
|
|
2244
|
+
```csharp
|
|
2245
|
+
using UnityEngine;
|
|
2246
|
+
using WallstopStudios.UnityHelpers.Core.Random;
|
|
2247
|
+
using WallstopStudios.UnityHelpers.Core.Extension;
|
|
2248
|
+
|
|
2249
|
+
public class LevelGenerator : MonoBehaviour
|
|
2250
|
+
{
|
|
2251
|
+
private IRandom random;
|
|
2252
|
+
|
|
2253
|
+
public void GenerateLevel(int seed)
|
|
2254
|
+
{
|
|
2255
|
+
random = new PcgRandom(seed); // Deterministic - same seed = same level
|
|
2256
|
+
|
|
2257
|
+
// Generate noise map for terrain height
|
|
2258
|
+
float[,] heightMap = random.NextNoiseMap(
|
|
2259
|
+
width: 256,
|
|
2260
|
+
height: 256,
|
|
2261
|
+
octaves: 4,
|
|
2262
|
+
persistence: 0.5f,
|
|
2263
|
+
lacunarity: 2f
|
|
2264
|
+
);
|
|
2265
|
+
|
|
2266
|
+
// Place terrain features based on height
|
|
2267
|
+
for (int x = 0; x < 256; x++)
|
|
2268
|
+
{
|
|
2269
|
+
for (int y = 0; y < 256; y++)
|
|
2270
|
+
{
|
|
2271
|
+
float height = heightMap[x, y];
|
|
2272
|
+
|
|
2273
|
+
if (height > 0.7f) PlaceMountain(x, y);
|
|
2274
|
+
else if (height > 0.4f) PlaceTree(x, y);
|
|
2275
|
+
else if (height < 0.3f) PlaceWater(x, y);
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2279
|
+
// Spawn enemy clusters using Gaussian distribution
|
|
2280
|
+
int clusterCount = random.Next(5, 10);
|
|
2281
|
+
for (int i = 0; i < clusterCount; i++)
|
|
2282
|
+
{
|
|
2283
|
+
Vector2 clusterCenter = random.NextVector2() * 256f;
|
|
2284
|
+
int enemiesInCluster = random.Next(3, 8);
|
|
2285
|
+
|
|
2286
|
+
for (int j = 0; j < enemiesInCluster; j++)
|
|
2287
|
+
{
|
|
2288
|
+
// Cluster tightly around center
|
|
2289
|
+
Vector2 offset = new Vector2(
|
|
2290
|
+
random.NextGaussian(mean: 0f, stdDev: 10f),
|
|
2291
|
+
random.NextGaussian(mean: 0f, stdDev: 10f)
|
|
2292
|
+
);
|
|
2293
|
+
|
|
2294
|
+
SpawnEnemy(clusterCenter + offset);
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
// Place collectibles with distance requirements
|
|
2299
|
+
List<Vector2> itemPositions = new();
|
|
2300
|
+
int itemCount = random.Next(20, 30);
|
|
2301
|
+
|
|
2302
|
+
for (int i = 0; i < itemCount; i++)
|
|
2303
|
+
{
|
|
2304
|
+
Vector2 pos;
|
|
2305
|
+
int attempts = 0;
|
|
2306
|
+
|
|
2307
|
+
// Ensure minimum spacing between items
|
|
2308
|
+
do
|
|
2309
|
+
{
|
|
2310
|
+
pos = random.NextVector2() * 256f;
|
|
2311
|
+
attempts++;
|
|
2312
|
+
}
|
|
2313
|
+
while (attempts < 10 && itemPositions.Any(p => Vector2.Distance(p, pos) < 15f));
|
|
2314
|
+
|
|
2315
|
+
itemPositions.Add(pos);
|
|
2316
|
+
PlaceCollectible(pos);
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
```
|
|
2321
|
+
|
|
2322
|
+
**Advanced features showcased:**
|
|
2323
|
+
|
|
2324
|
+
- **NextNoiseMap():** Complete Perlin noise implementation in one call
|
|
2325
|
+
- **NextGaussian():** Natural clustering (bell curve distribution)
|
|
2326
|
+
- **NextVector2():** Cleaner than `new Vector2(random.NextFloat(), random.NextFloat())`
|
|
2327
|
+
- **Seedable:** Perfect for networked games or replay systems
|
|
2328
|
+
|
|
2329
|
+
---
|
|
2330
|
+
|
|
2331
|
+
### Case Study: AI Behavior with Spatial Queries
|
|
2332
|
+
|
|
2333
|
+
Efficient enemy AI that scales to hundreds of units using spatial trees.
|
|
2334
|
+
|
|
2335
|
+
```csharp
|
|
2336
|
+
using UnityEngine;
|
|
2337
|
+
using WallstopStudios.UnityHelpers.Core.DataStructure;
|
|
2338
|
+
using WallstopStudios.UnityHelpers.Core.Attributes;
|
|
2339
|
+
using WallstopStudios.UnityHelpers.Core.Random;
|
|
2340
|
+
|
|
2341
|
+
public class AIController : MonoBehaviour
|
|
2342
|
+
{
|
|
2343
|
+
[SiblingComponent] private NavMeshAgent agent;
|
|
2344
|
+
[SiblingComponent] private Animator animator;
|
|
2345
|
+
|
|
2346
|
+
private IRandom random;
|
|
2347
|
+
private QuadTree2D<Enemy> enemyTree;
|
|
2348
|
+
private List<Enemy> nearbyBuffer = new(32); // Reusable buffer
|
|
2349
|
+
|
|
2350
|
+
void Start()
|
|
2351
|
+
{
|
|
2352
|
+
this.AssignRelationalComponents();
|
|
2353
|
+
|
|
2354
|
+
// Deterministic AI with seeded random
|
|
2355
|
+
random = new PcgRandom(seed: GetInstanceID());
|
|
2356
|
+
|
|
2357
|
+
// Build spatial tree for O(log n) queries
|
|
2358
|
+
enemyTree = new QuadTree2D<Enemy>(
|
|
2359
|
+
FindObjectsOfType<Enemy>(),
|
|
2360
|
+
e => e.transform.position
|
|
2361
|
+
);
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
void Update()
|
|
2365
|
+
{
|
|
2366
|
+
nearbyBuffer.Clear();
|
|
2367
|
+
|
|
2368
|
+
// Fast O(log n) query instead of O(n) distance checks
|
|
2369
|
+
enemyTree.GetElementsInRange(transform.position, 20f, nearbyBuffer);
|
|
2370
|
+
|
|
2371
|
+
if (nearbyBuffer.Count > 0)
|
|
2372
|
+
{
|
|
2373
|
+
// Weighted selection - prefer closer targets
|
|
2374
|
+
float[] weights = nearbyBuffer.Select(e =>
|
|
2375
|
+
1f / Vector2.Distance(transform.position, e.transform.position)
|
|
2376
|
+
).ToArray();
|
|
2377
|
+
|
|
2378
|
+
int targetIndex = random.NextWeightedIndex(weights);
|
|
2379
|
+
Enemy target = nearbyBuffer[targetIndex];
|
|
2380
|
+
|
|
2381
|
+
agent.SetDestination(target.transform.position);
|
|
2382
|
+
animator.SetBool("IsChasing", true);
|
|
2383
|
+
}
|
|
2384
|
+
else
|
|
2385
|
+
{
|
|
2386
|
+
animator.SetBool("IsChasing", false);
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
```
|
|
2391
|
+
|
|
2392
|
+
**Performance wins:**
|
|
2393
|
+
|
|
2394
|
+
- **O(log n) queries:** Find nearby enemies without checking every object
|
|
2395
|
+
- **Buffering pattern:** Reuse `nearbyBuffer` to avoid GC
|
|
2396
|
+
- **Scales to 1000+ units:** QuadTree keeps queries fast even with many objects
|
|
2397
|
+
|
|
2398
|
+
**When to use spatial trees:**
|
|
2399
|
+
|
|
2400
|
+
- Many moving objects (enemies, bullets, particles)
|
|
2401
|
+
- Frequent proximity checks (AI awareness, collision)
|
|
2402
|
+
- Large open worlds (visibility culling)
|
|
2403
|
+
|
|
2404
|
+
**Guides:** [2D Spatial Trees](SPATIAL_TREES_2D_GUIDE.md) | [Performance Benchmarks](SPATIAL_TREE_2D_PERFORMANCE.md)
|
|
2405
|
+
|
|
2406
|
+
## Hidden Gems: Underrated Killer Features
|
|
2407
|
+
|
|
2408
|
+
These powerful utilities solve common game development problems but might not be immediately obvious from the feature list.
|
|
2409
|
+
|
|
2410
|
+
### Predictive Targeting: Hit Moving Targets
|
|
2411
|
+
|
|
2412
|
+
Perfect ballistics in one line. Calculates the intercept point for hitting a moving target with a projectile of known speed.
|
|
2413
|
+
|
|
2414
|
+
```csharp
|
|
2415
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
2416
|
+
|
|
2417
|
+
public class Turret : MonoBehaviour
|
|
2418
|
+
{
|
|
2419
|
+
public float projectileSpeed = 25f;
|
|
2420
|
+
|
|
2421
|
+
void Update()
|
|
2422
|
+
{
|
|
2423
|
+
GameObject target = FindTarget();
|
|
2424
|
+
if (target == null) return;
|
|
2425
|
+
|
|
2426
|
+
// Estimate target velocity (or track it)
|
|
2427
|
+
Vector2 targetVelocity = EstimateVelocity(target);
|
|
2428
|
+
|
|
2429
|
+
// Calculate perfect aim point accounting for projectile travel time
|
|
2430
|
+
Vector2 aimPoint = target.PredictCurrentTarget(
|
|
2431
|
+
launchLocation: transform.position,
|
|
2432
|
+
projectileSpeed: projectileSpeed,
|
|
2433
|
+
predictiveFiring: true,
|
|
2434
|
+
targetVelocity: targetVelocity
|
|
2435
|
+
);
|
|
2436
|
+
|
|
2437
|
+
// Aim and fire
|
|
2438
|
+
transform.up = (aimPoint - (Vector2)transform.position).normalized;
|
|
2439
|
+
Fire();
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
```
|
|
2443
|
+
|
|
2444
|
+
**Why this is a game-changer:**
|
|
2445
|
+
|
|
2446
|
+
- Solves quadratic intercept equation with robust fallbacks for edge cases
|
|
2447
|
+
- Handles fast/slow projectiles, moving/stationary targets automatically
|
|
2448
|
+
- Perfect for: turrets, homing missiles, AI prediction, physics-based games
|
|
2449
|
+
- Eliminates need for iterative aiming or complex prediction logic
|
|
2450
|
+
|
|
2451
|
+
**Real-world use case:** Tower defense games where enemies move along paths - turrets lead the target perfectly without any tuning.
|
|
2452
|
+
|
|
2453
|
+
---
|
|
2454
|
+
|
|
2455
|
+
### ReflectionHelpers: Blazing-Fast Reflection
|
|
2456
|
+
|
|
2457
|
+
High-performance reflection using IL emission and expression compilation. 10-100x faster than System.Reflection for hot paths.
|
|
2458
|
+
|
|
2459
|
+
```csharp
|
|
2460
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
2461
|
+
using System.Reflection;
|
|
2462
|
+
|
|
2463
|
+
// ONE-TIME: Create cached delegates (do this at initialization)
|
|
2464
|
+
FieldInfo healthField = typeof(Enemy).GetField("_health", BindingFlags.NonPublic | BindingFlags.Instance);
|
|
2465
|
+
var getHealth = ReflectionHelpers.GetFieldGetter(healthField); // Cached
|
|
2466
|
+
var setHealth = ReflectionHelpers.GetFieldSetter(healthField); // Cached
|
|
2467
|
+
|
|
2468
|
+
// HOT PATH: Use the delegates (10-100x faster than reflection)
|
|
2469
|
+
void ProcessEnemies(List<object> enemies)
|
|
2470
|
+
{
|
|
2471
|
+
foreach (object enemy in enemies)
|
|
2472
|
+
{
|
|
2473
|
+
float health = (float)getHealth(enemy);
|
|
2474
|
+
setHealth(enemy, health - 10f);
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
```
|
|
2478
|
+
|
|
2479
|
+
**Advanced: Typed accessors for zero boxing**
|
|
2480
|
+
|
|
2481
|
+
```csharp
|
|
2482
|
+
// For structs or when you need maximum performance
|
|
2483
|
+
FieldInfo scoreField = typeof(Player).GetField("Score");
|
|
2484
|
+
var getScore = ReflectionHelpers.GetFieldGetter<Player, int>(scoreField);
|
|
2485
|
+
var setScore = ReflectionHelpers.GetFieldSetter<Player, int>(scoreField);
|
|
2486
|
+
|
|
2487
|
+
Player player = new Player();
|
|
2488
|
+
setScore(ref player, 100); // No boxing, direct struct mutation
|
|
2489
|
+
int score = getScore(ref player);
|
|
2490
|
+
```
|
|
2491
|
+
|
|
2492
|
+
**Why this is essential:**
|
|
2493
|
+
|
|
2494
|
+
- **Serialization systems**: Deserialize thousands of objects per frame
|
|
2495
|
+
- **Data binding**: UI systems that update from model properties
|
|
2496
|
+
- **Modding APIs**: Safe access to private fields without making everything public
|
|
2497
|
+
- **ECS-style systems**: Generic component access without inheritance
|
|
2498
|
+
- **IL2CPP safe**: Works with Unity's aggressive compilation
|
|
2499
|
+
|
|
2500
|
+
**Performance numbers:** GetField: ~2ns vs ~200ns (100x), SetField: ~3ns vs ~150ns (50x)
|
|
2501
|
+
|
|
2502
|
+
---
|
|
2503
|
+
|
|
2504
|
+
### Professional-Grade Object Pooling
|
|
2505
|
+
|
|
2506
|
+
Thread-safe pooling for Lists, Arrays, Dictionaries, and custom types with automatic cleanup via IDisposable pattern.
|
|
2507
|
+
|
|
2508
|
+
```csharp
|
|
2509
|
+
using WallstopStudios.UnityHelpers.Utils;
|
|
2510
|
+
using WallstopStudios.UnityHelpers.Core.DataStructure;
|
|
2511
|
+
|
|
2512
|
+
public class ParticleSystem : MonoBehaviour
|
|
2513
|
+
{
|
|
2514
|
+
void Update()
|
|
2515
|
+
{
|
|
2516
|
+
// Get pooled list - automatically returned on scope exit
|
|
2517
|
+
using var lease = Buffers<Vector3>.List.Get(out List<Vector3> positions);
|
|
2518
|
+
|
|
2519
|
+
// Use it freely
|
|
2520
|
+
CalculateParticlePositions(positions);
|
|
2521
|
+
|
|
2522
|
+
// Do spatial query with pooled buffer
|
|
2523
|
+
using var enemiesLease = Buffers<Enemy>.List.Get(out List<Enemy> enemies);
|
|
2524
|
+
enemyTree.GetElementsInRange(transform.position, 10f, enemies);
|
|
2525
|
+
|
|
2526
|
+
foreach (Enemy enemy in enemies)
|
|
2527
|
+
{
|
|
2528
|
+
enemy.TakeDamage(1f);
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2531
|
+
// Both lists automatically returned to pool here - zero cleanup code
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
```
|
|
2535
|
+
|
|
2536
|
+
**Advanced: Pooled arrays for high-frequency operations**
|
|
2537
|
+
|
|
2538
|
+
```csharp
|
|
2539
|
+
void ProcessFrame(int vertexCount)
|
|
2540
|
+
{
|
|
2541
|
+
// Rent array from pool
|
|
2542
|
+
using var lease = WallstopArrayPool<Vector3>.Get(vertexCount, out Vector3[] vertices);
|
|
2543
|
+
|
|
2544
|
+
// Use it for processing
|
|
2545
|
+
mesh.GetVertices(vertices);
|
|
2546
|
+
TransformVertices(vertices);
|
|
2547
|
+
mesh.SetVertices(vertices);
|
|
2548
|
+
|
|
2549
|
+
// Array automatically returned and cleared
|
|
2550
|
+
}
|
|
2551
|
+
```
|
|
2552
|
+
|
|
2553
|
+
**Why this matters:**
|
|
2554
|
+
|
|
2555
|
+
- **Zero GC spikes**: Reuse allocations instead of creating garbage
|
|
2556
|
+
- **Automatic cleanup**: IDisposable pattern ensures returns even on exceptions
|
|
2557
|
+
- **Thread-safe**: ConcurrentStack backing for multi-threaded scenarios
|
|
2558
|
+
- **Type-safe**: Generic pooling with full type safety
|
|
2559
|
+
- **Customizable**: Create pools for your own types with custom lifecycle callbacks
|
|
2560
|
+
|
|
2561
|
+
**Perfect for:**
|
|
2562
|
+
|
|
2563
|
+
- AI systems querying neighbors every frame
|
|
2564
|
+
- Particle systems with thousands of particles
|
|
2565
|
+
- Physics raycasts returning hit arrays
|
|
2566
|
+
- UI systems updating hundreds of elements
|
|
2567
|
+
- Any system doing frequent spatial queries
|
|
2568
|
+
|
|
2569
|
+
---
|
|
2570
|
+
|
|
2571
|
+
### Lifecycle Helpers: No More DestroyImmediate Bugs
|
|
2572
|
+
|
|
2573
|
+
Safe object destruction that works correctly in both edit mode and play mode, preventing scene corruption.
|
|
2574
|
+
|
|
2575
|
+
```csharp
|
|
2576
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
2577
|
+
|
|
2578
|
+
public class DynamicUI : MonoBehaviour
|
|
2579
|
+
{
|
|
2580
|
+
void RebuildUI()
|
|
2581
|
+
{
|
|
2582
|
+
// ❌ WRONG: Can corrupt scenes in edit mode
|
|
2583
|
+
// foreach (Transform child in transform)
|
|
2584
|
+
// DestroyImmediate(child.gameObject);
|
|
2585
|
+
|
|
2586
|
+
// ✅ RIGHT: Works safely in both modes
|
|
2587
|
+
transform.gameObject.DestroyAllChildrenGameObjects();
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
void CleanupEffect(GameObject effect)
|
|
2591
|
+
{
|
|
2592
|
+
// Automatically uses DestroyImmediate in editor, Destroy at runtime
|
|
2593
|
+
effect.SmartDestroy();
|
|
2594
|
+
|
|
2595
|
+
// Or with delay (runtime only)
|
|
2596
|
+
effect.SmartDestroy(afterTime: 2f);
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
```
|
|
2600
|
+
|
|
2601
|
+
**GetOrAddComponent: Idempotent Component Setup**
|
|
2602
|
+
|
|
2603
|
+
```csharp
|
|
2604
|
+
public class PlayerSetup : MonoBehaviour
|
|
2605
|
+
{
|
|
2606
|
+
void Initialize()
|
|
2607
|
+
{
|
|
2608
|
+
// Always safe - adds only if missing
|
|
2609
|
+
Rigidbody2D rb = gameObject.GetOrAddComponent<Rigidbody2D>();
|
|
2610
|
+
rb.gravityScale = 0;
|
|
2611
|
+
|
|
2612
|
+
// Works with non-generic too
|
|
2613
|
+
Component collider = gameObject.GetOrAddComponent(typeof(CircleCollider2D));
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
```
|
|
2617
|
+
|
|
2618
|
+
**Why these are essential:**
|
|
2619
|
+
|
|
2620
|
+
- `SmartDestroy`: Prevents "Destroying assets is not permitted" errors in editor
|
|
2621
|
+
- `DestroyAllChildren*`: Cleans hierarchies without index shifting bugs
|
|
2622
|
+
- `GetOrAddComponent`: Initialization code that's safe to run multiple times
|
|
2623
|
+
- All methods handle null checks and edge cases
|
|
2624
|
+
- Works correctly with prefab editing mode
|
|
2625
|
+
|
|
2626
|
+
**Common scenarios:**
|
|
2627
|
+
|
|
2628
|
+
- Editor tools that modify hierarchies
|
|
2629
|
+
- Runtime UI builders
|
|
2630
|
+
- Procedural content generation
|
|
2631
|
+
- Testing/setup code that runs multiple times
|
|
2632
|
+
|
|
2633
|
+
---
|
|
2634
|
+
|
|
2635
|
+
### Convex & Concave Hull Generation
|
|
2636
|
+
|
|
2637
|
+
Production-ready implementations of hull generation algorithms for complex shapes from point clouds.
|
|
2638
|
+
|
|
2639
|
+
```csharp
|
|
2640
|
+
using WallstopStudios.UnityHelpers.Core.Extension;
|
|
2641
|
+
using System.Collections.Generic;
|
|
2642
|
+
|
|
2643
|
+
public class TerrainOutline : MonoBehaviour
|
|
2644
|
+
{
|
|
2645
|
+
void GenerateOutline(List<Vector2> terrainPoints)
|
|
2646
|
+
{
|
|
2647
|
+
// Convex hull (fast, for simple outer bounds)
|
|
2648
|
+
List<Vector2> convexHull = terrainPoints.BuildConvexHull(
|
|
2649
|
+
algorithm: UnityExtensions.ConvexHullAlgorithm.MonotoneChain
|
|
2650
|
+
);
|
|
2651
|
+
|
|
2652
|
+
// Concave hull (slower, but follows terrain shape closely)
|
|
2653
|
+
List<FastVector3Int> gridPositions = GetTerrainGridPositions();
|
|
2654
|
+
var options = new UnityExtensions.ConcaveHullOptions
|
|
2655
|
+
{
|
|
2656
|
+
Strategy = UnityExtensions.ConcaveHullStrategy.Knn,
|
|
2657
|
+
NearestNeighbors = 5 // Lower = tighter fit, higher = smoother
|
|
2658
|
+
};
|
|
2659
|
+
List<FastVector3Int> concaveHull = gridPositions.BuildConcaveHull(
|
|
2660
|
+
grid: GetComponent<Grid>(),
|
|
2661
|
+
options: options
|
|
2662
|
+
);
|
|
2663
|
+
|
|
2664
|
+
// Use for collider generation, fog of war, territory borders, etc.
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
```
|
|
2668
|
+
|
|
2669
|
+
**Why this is powerful:**
|
|
2670
|
+
|
|
2671
|
+
- **Convex hulls**: Perfect for collision bounds, fog of war outer limits, vision cones
|
|
2672
|
+
- **Concave hulls**: Detailed territory borders, minimap fog, destructible terrain
|
|
2673
|
+
- Multiple algorithms: MonotoneChain (fast), Jarvis (simple), Knn/EdgeSplit (concave)
|
|
2674
|
+
- Grid-aware: Works with Unity Tilemap/Grid systems out of the box
|
|
2675
|
+
|
|
2676
|
+
**Real-world uses:**
|
|
2677
|
+
|
|
2678
|
+
- RTS territory visualization
|
|
2679
|
+
- Fog of war boundaries
|
|
2680
|
+
- Destructible terrain collision
|
|
2681
|
+
- Minimap zone outlines
|
|
2682
|
+
- Vision cone generation
|
|
2683
|
+
|
|
2684
|
+
---
|
|
2685
|
+
|
|
2686
|
+
### Coroutine Timing with Jitter
|
|
2687
|
+
|
|
2688
|
+
Production-ready timing utilities with staggered starts to prevent frame spikes.
|
|
2689
|
+
|
|
2690
|
+
```csharp
|
|
2691
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
2692
|
+
|
|
2693
|
+
public class HealthRegen : MonoBehaviour
|
|
2694
|
+
{
|
|
2695
|
+
void Start()
|
|
2696
|
+
{
|
|
2697
|
+
// Poll every 0.5s with random initial delay (prevents all enemies syncing)
|
|
2698
|
+
this.StartFunctionAsCoroutine(
|
|
2699
|
+
action: RegenHealth,
|
|
2700
|
+
updateRate: 0.5f,
|
|
2701
|
+
useJitter: true // Adds 0-0.5s random initial delay
|
|
2702
|
+
);
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
void RegenHealth()
|
|
2706
|
+
{
|
|
2707
|
+
health += regenPerTick;
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
```
|
|
2711
|
+
|
|
2712
|
+
**Why jitter matters:**
|
|
2713
|
+
|
|
2714
|
+
- **Prevents frame spikes**: 100 enemies all polling at once = lag spike
|
|
2715
|
+
- **Distributes load**: Staggers work across multiple frames
|
|
2716
|
+
- **Simple API**: One parameter prevents performance issues
|
|
2717
|
+
|
|
2718
|
+
**Other timing helpers:**
|
|
2719
|
+
|
|
2720
|
+
```csharp
|
|
2721
|
+
// Execute after delay
|
|
2722
|
+
this.ExecuteFunctionAfterDelay(() => SpawnBoss(), delay: 3f);
|
|
2723
|
+
|
|
2724
|
+
// Execute next frame
|
|
2725
|
+
this.ExecuteFunctionNextFrame(() => RefreshUI());
|
|
2726
|
+
|
|
2727
|
+
// Execute at end of frame (after rendering)
|
|
2728
|
+
this.ExecuteFunctionAfterFrame(() => CaptureScreenshot());
|
|
2729
|
+
|
|
2730
|
+
// Execute N times over duration
|
|
2731
|
+
StartCoroutine(Helpers.ExecuteOverTime(
|
|
2732
|
+
action: () => SpawnMinion(),
|
|
2733
|
+
totalCount: 10,
|
|
2734
|
+
duration: 5f,
|
|
2735
|
+
delay: true // Space evenly over duration
|
|
2736
|
+
));
|
|
2737
|
+
```
|
|
2738
|
+
|
|
2739
|
+
---
|
|
2740
|
+
|
|
2741
|
+
### Cached Lookups: Find<T> with Tag Caching
|
|
2742
|
+
|
|
2743
|
+
Eliminates repeated GameObject.FindGameObjectWithTag calls with automatic caching.
|
|
2744
|
+
|
|
2745
|
+
```csharp
|
|
2746
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
2747
|
+
|
|
2748
|
+
public class GameController : MonoBehaviour
|
|
2749
|
+
{
|
|
2750
|
+
void Update()
|
|
2751
|
+
{
|
|
2752
|
+
// First call: searches scene and caches
|
|
2753
|
+
// Subsequent calls: instant lookup from cache
|
|
2754
|
+
AudioManager audio = Helpers.Find<AudioManager>("AudioManager");
|
|
2755
|
+
audio.PlaySound("Click");
|
|
2756
|
+
|
|
2757
|
+
// From within a component (for logging context)
|
|
2758
|
+
PlayerData data = this.Find<PlayerData>("PlayerData");
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
```
|
|
2762
|
+
|
|
2763
|
+
**Why this helps:**
|
|
2764
|
+
|
|
2765
|
+
- **Automatic caching**: First call populates cache, subsequent calls are O(1)
|
|
2766
|
+
- **Fail-fast**: Logs warnings when tags are missing (can disable)
|
|
2767
|
+
- **Memory efficient**: Only caches what you actually use
|
|
2768
|
+
- **Invalidation safe**: Removes stale entries automatically
|
|
2769
|
+
|
|
2770
|
+
---
|
|
2771
|
+
|
|
2772
|
+
### UI Toolkit Progress Bars
|
|
2773
|
+
|
|
2774
|
+
Professional progress bar components with multiple visual styles, ready to use.
|
|
2775
|
+
|
|
2776
|
+
```csharp
|
|
2777
|
+
// Available styles:
|
|
2778
|
+
// - CircularProgressBar: Circular/radial progress
|
|
2779
|
+
// - RegularProgressBar: Traditional horizontal/vertical
|
|
2780
|
+
// - LiquidProgressBar: Liquid/wave effect
|
|
2781
|
+
// - GlitchProgressBar: Glitch/cyberpunk effect
|
|
2782
|
+
// - MarchingAntsProgressBar: Animated border
|
|
2783
|
+
// - WigglyProgressBar: Wavy animation
|
|
2784
|
+
// - ArcedProgressBar: Partial arc/gauge
|
|
2785
|
+
|
|
2786
|
+
// Use in UXML or code
|
|
2787
|
+
var progressBar = new CircularProgressBar
|
|
2788
|
+
{
|
|
2789
|
+
Progress = 0.75f,
|
|
2790
|
+
Radius = 50f,
|
|
2791
|
+
Thickness = 10f,
|
|
2792
|
+
Direction = CircularProgressBar.FillDirection.Clockwise,
|
|
2793
|
+
TrackColor = Color.gray,
|
|
2794
|
+
ProgressColor = Color.green
|
|
2795
|
+
};
|
|
2796
|
+
```
|
|
2797
|
+
|
|
2798
|
+
**Located in:** `Styles/Elements/Progress/`
|
|
2799
|
+
|
|
2800
|
+
---
|
|
2801
|
+
|
|
2802
|
+
## Performance
|
|
2803
|
+
|
|
2804
|
+
Unity Helpers is built with performance as a top priority. Here are some key metrics:
|
|
2805
|
+
|
|
2806
|
+
### Random Number Generation
|
|
2807
|
+
|
|
2808
|
+
Unity Helpers' random number generators are **10-15x faster** than Unity's built-in `UnityEngine.Random`:
|
|
2809
|
+
|
|
2810
|
+
- **UnityRandom**: 83M operations/sec
|
|
2811
|
+
- **IllusionFlow** (PRNG.Instance): 609M operations/sec (**7x faster**)
|
|
2812
|
+
- **RomuDuo** (fastest): 877M operations/sec (**10.5x faster**)
|
|
2813
|
+
|
|
2814
|
+
[📊 Full Random Performance Benchmarks](RANDOM_PERFORMANCE.md)
|
|
2815
|
+
|
|
2816
|
+
### Spatial Trees
|
|
2817
|
+
|
|
2818
|
+
Spatial queries are dramatically faster than linear searches:
|
|
2819
|
+
|
|
2820
|
+
| Objects | Linear Search | QuadTree2D | Speedup |
|
|
2821
|
+
| --------- | ------------- | ------------ | ------------ |
|
|
2822
|
+
| 1,000 | 1M ops/sec | 283M ops/sec | **283x** |
|
|
2823
|
+
| 10,000 | 100K ops/sec | 233M ops/sec | **2,330x** |
|
|
2824
|
+
| 100,000 | 10K ops/sec | 174M ops/sec | **17,400x** |
|
|
2825
|
+
| 1,000,000 | 1K ops/sec | 141M ops/sec | **141,000x** |
|
|
2826
|
+
|
|
2827
|
+
_Measurements for small radius queries (1 unit)_
|
|
2828
|
+
|
|
2829
|
+
[📊 2D Spatial Tree Benchmarks](SPATIAL_TREE_2D_PERFORMANCE.md) | [📊 3D Spatial Tree Benchmarks](SPATIAL_TREE_3D_PERFORMANCE.md)
|
|
2830
|
+
|
|
2831
|
+
### Editor Performance
|
|
2832
|
+
|
|
2833
|
+
Editor tools use optimizations like:
|
|
2834
|
+
|
|
2835
|
+
- Parallel processing for image operations
|
|
2836
|
+
- Cached reflection for attribute systems
|
|
2837
|
+
- Batch asset database operations
|
|
2838
|
+
- Progress bars for long operations
|
|
2839
|
+
|
|
2840
|
+
## Contributing
|
|
2841
|
+
|
|
2842
|
+
We welcome contributions! This project uses [CSharpier](https://csharpier.com/) for consistent code formatting.
|
|
2843
|
+
|
|
2844
|
+
### Before Contributing
|
|
2845
|
+
|
|
2846
|
+
1. Install [CSharpier](https://csharpier.com/) (via editor plugin or CLI)
|
|
2847
|
+
2. Format changed files before committing
|
|
2848
|
+
3. Consider installing the [pre-commit hook](https://pre-commit.com/#3-install-the-git-hook-scripts)
|
|
2849
|
+
|
|
2850
|
+
### How to Contribute
|
|
2851
|
+
|
|
2852
|
+
1. Fork the repository
|
|
2853
|
+
2. Create a feature branch
|
|
2854
|
+
3. Make your changes and format with CSharpier
|
|
2855
|
+
4. Write/update tests if applicable
|
|
2856
|
+
5. Submit a pull request
|
|
2857
|
+
|
|
2858
|
+
### Reporting Issues
|
|
2859
|
+
|
|
2860
|
+
Found a bug or have a feature request? [Open an issue](https://github.com/wallstop/unity-helpers/issues) on GitHub.
|
|
2861
|
+
|
|
2862
|
+
## License
|
|
2863
|
+
|
|
2864
|
+
[MIT License](LICENSE)
|
|
2865
|
+
|
|
2866
|
+
---
|
|
2867
|
+
|
|
2868
|
+
## Relational Components Guide
|
|
2869
|
+
|
|
2870
|
+
For a complete, user-friendly walkthrough of `[ParentComponent]`, `[ChildComponent]`, and `[SiblingComponent]` including examples, recipes, and FAQs, see:
|
|
2871
|
+
|
|
2872
|
+
- [Relational Components](RELATIONAL_COMPONENTS.md)
|
|
2873
|
+
|
|
2874
|
+
Troubleshooting common issues (runtime-only assignment, filters, depth, inactive objects):
|
|
2875
|
+
|
|
2876
|
+
- [Relational Components — Troubleshooting](RELATIONAL_COMPONENTS.md#troubleshooting)
|
|
2877
|
+
|
|
2878
|
+
---
|
|
2879
|
+
|
|
2880
|
+
## Additional Resources
|
|
2881
|
+
|
|
2882
|
+
- [Editor Tools Guide](EDITOR_TOOLS_GUIDE.md) - Complete documentation for all editor tools
|
|
2883
|
+
- [Relational Components Guide](RELATIONAL_COMPONENTS.md) - Sibling/Parent/Child attributes with examples
|
|
2884
|
+
- [Random Performance](RANDOM_PERFORMANCE.md) - Detailed RNG benchmarks
|
|
2885
|
+
- [2D Spatial Trees](SPATIAL_TREE_2D_PERFORMANCE.md) - 2D spatial tree benchmarks
|
|
2886
|
+
- [3D Spatial Trees](SPATIAL_TREE_3D_PERFORMANCE.md) - 3D spatial tree benchmarks
|
|
2887
|
+
- [GitHub Repository](https://github.com/wallstop/unity-helpers)
|
|
2888
|
+
- [Issue Tracker](https://github.com/wallstop/unity-helpers/issues)
|
|
2889
|
+
- [NPM Package](https://www.npmjs.com/package/com.wallstop-studios.unity-helpers)
|
|
2890
|
+
|
|
2891
|
+
---
|
|
2892
|
+
|
|
2893
|
+
---
|
|
2894
|
+
|
|
2895
|
+
## 📚 Related Documentation
|
|
2896
|
+
|
|
2897
|
+
**Quick Start:**
|
|
2898
|
+
|
|
2899
|
+
- [Getting Started Guide](GETTING_STARTED.md) - Your first 5 minutes with Unity Helpers
|
|
2900
|
+
- [Feature Index](INDEX.md) - Alphabetical reference of all features
|
|
2901
|
+
- [Glossary](GLOSSARY.md) - Term definitions and concepts
|
|
2902
|
+
|
|
2903
|
+
**Core Guides:**
|
|
2904
|
+
|
|
2905
|
+
- [Relational Components](RELATIONAL_COMPONENTS.md) - Auto-wiring component references
|
|
2906
|
+
- [Effects System](EFFECTS_SYSTEM.md) - Data-driven buff/debuff system
|
|
2907
|
+
- [Serialization](SERIALIZATION.md) - Save systems and networking
|
|
2908
|
+
- [Editor Tools](EDITOR_TOOLS_GUIDE.md) - Asset pipeline automation
|
|
2909
|
+
- [Math & Extensions](MATH_AND_EXTENSIONS.md) - Core utilities and helpers
|
|
2910
|
+
|
|
2911
|
+
**Spatial Trees:**
|
|
2912
|
+
|
|
2913
|
+
- [2D Spatial Trees Guide](SPATIAL_TREES_2D_GUIDE.md) - QuadTree, KDTree, RTree
|
|
2914
|
+
- [3D Spatial Trees Guide](SPATIAL_TREES_3D_GUIDE.md) - OctTree, KDTree3D, RTree3D
|
|
2915
|
+
- [Spatial Tree Semantics](SPATIAL_TREE_SEMANTICS.md) - Boundary behavior details
|
|
2916
|
+
- [2D Performance](SPATIAL_TREE_2D_PERFORMANCE.md) | [3D Performance](SPATIAL_TREE_3D_PERFORMANCE.md)
|
|
2917
|
+
|
|
2918
|
+
**Advanced:**
|
|
2919
|
+
|
|
2920
|
+
- [Reflection Helpers](REFLECTION_HELPERS.md) - High-performance reflection
|
|
2921
|
+
- [Data Structures](DATA_STRUCTURES.md) - Heaps, tries, sparse sets
|
|
2922
|
+
- [Singletons](SINGLETONS.md) - Runtime and ScriptableObject patterns
|
|
2923
|
+
|
|
2924
|
+
**DI Integration:**
|
|
2925
|
+
|
|
2926
|
+
- [VContainer Sample](Samples~/DI%20-%20VContainer/README.md) - VContainer integration
|
|
2927
|
+
- [Zenject Sample](Samples~/DI%20-%20Zenject/README.md) - Zenject integration
|
|
2928
|
+
|
|
2929
|
+
**Need help?** [Open an issue](https://github.com/wallstop/unity-helpers/issues) | [Discussions](https://github.com/wallstop/unity-helpers/discussions)
|
|
2930
|
+
|
|
2931
|
+
---
|
|
2932
|
+
|
|
2933
|
+
**Made with ❤️ by [Wallstop Studios](https://wallstopstudios.com)**
|
|
2934
|
+
|
|
2935
|
+
_Unity Helpers is production-ready and actively maintained. Star the repo if you find it useful!_
|
|
2936
|
+
|
|
2937
|
+
## API Index
|
|
2938
|
+
|
|
2939
|
+
- Namespaces
|
|
2940
|
+
- `WallstopStudios.UnityHelpers.Core.Helper`
|
|
2941
|
+
- `Helpers` — General utilities (layers, sprites, components, math, pooling)
|
|
2942
|
+
- `Objects` — Unity-aware null checks and deterministic hashing
|
|
2943
|
+
- `WallMath` — Positive modulo, wrapped add/increment, bounded floats/doubles
|
|
2944
|
+
- `LineHelper` — Douglas–Peucker polyline simplification
|
|
2945
|
+
- `Geometry` — Rect accumulation, sidedness tests
|
|
2946
|
+
- `PathHelper`/`FileHelper`/`DirectoryHelper` — File and path utilities (editor/runtime)
|
|
2947
|
+
- `SceneHelper` — Scene discovery and object retrieval (with disposal scope)
|
|
2948
|
+
- `SpriteHelpers` — Make textures readable (editor)
|
|
2949
|
+
- `UnityMainThreadDispatcher` — Enqueue work for main thread
|
|
2950
|
+
- [`ReflectionHelpers`](REFLECTION_HELPERS.md) — High-performance field/property/method/ctor access and type scanning
|
|
2951
|
+
- `FormattingHelpers` — Human-friendly sizes (e.g., bytes)
|
|
2952
|
+
- `IterationHelpers` — 2D/3D array index enumeration
|
|
2953
|
+
- `FuncBasedComparer`/`ReverseComparer` — Comparer utilities
|
|
2954
|
+
- `StringInList` — Inspector dropdown for strings
|
|
2955
|
+
- `WallstopStudios.UnityHelpers.Core.Extension`
|
|
2956
|
+
- `UnityExtensions` — Unity-centric extensions (Rect/Bounds, Camera, Rigidbody2D, vectors)
|
|
2957
|
+
- `RandomExtensions` — Random vectors/quaternions/colors and selections
|
|
2958
|
+
- `StringExtensions` — Case transforms, UTF-8, JSON, Levenshtein
|
|
2959
|
+
- `IEnumerableExtensions` — Collection conversions, infinite sequences, shuffle
|
|
2960
|
+
- `IListExtensions`/`IReadonlyListExtensions` — Shuffle/shift/sort/search utilities
|
|
2961
|
+
- `DictionaryExtensions` — GetOrAdd, GetOrElse helpers
|
|
2962
|
+
- `AnimatorExtensions` — ResetTriggers convenience
|
|
2963
|
+
- `AsyncOperationExtensions` — Await `AsyncOperation` (Task/ValueTask)
|
|
2964
|
+
- `WallstopStudios.UnityHelpers.Core.DataStructure`
|
|
2965
|
+
- Point/Bounds trees: `QuadTree2D<T>`, `KdTree2D<T>`, `KdTree3D<T>`, `RTree2D<T>`, `RTree3D<T>`
|
|
2966
|
+
- Spatial hashes: `SpatialHash2D<T>`, `SpatialHash3D<T>`
|
|
2967
|
+
- General: `Heap<T>`, `PriorityQueue<T>`, `Deque<T>`, `Trie`, `BitSet`, `CyclicBuffer<T>`, `SparseSet<T>`
|
|
2968
|
+
|
|
2969
|
+
### Quick Start: ReflectionHelpers
|
|
2970
|
+
|
|
2971
|
+
```csharp
|
|
2972
|
+
using System;
|
|
2973
|
+
using System.Collections;
|
|
2974
|
+
using System.Collections.Generic;
|
|
2975
|
+
using System.Reflection;
|
|
2976
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
2977
|
+
|
|
2978
|
+
// 1) Fast field get/set (boxed)
|
|
2979
|
+
public sealed class Player { public int Score; }
|
|
2980
|
+
FieldInfo score = typeof(Player).GetField("Score");
|
|
2981
|
+
var getScore = ReflectionHelpers.GetFieldGetter(score); // object -> object
|
|
2982
|
+
var setScore = ReflectionHelpers.GetFieldSetter(score); // (object, object) -> void
|
|
2983
|
+
var p = new Player();
|
|
2984
|
+
setScore(p, 42);
|
|
2985
|
+
UnityEngine.Debug.Log((int)getScore(p)); // 42
|
|
2986
|
+
|
|
2987
|
+
// 2) Struct note: prefer typed ref setter
|
|
2988
|
+
public struct Stat { public int Value; }
|
|
2989
|
+
FieldInfo valueField = typeof(Stat).GetField("Value");
|
|
2990
|
+
var setValue = ReflectionHelpers.GetFieldSetter<Stat, int>(valueField);
|
|
2991
|
+
Stat s = default;
|
|
2992
|
+
setValue(ref s, 100); // s.Value == 100
|
|
2993
|
+
|
|
2994
|
+
// 3) Typed property getter
|
|
2995
|
+
PropertyInfo prop = typeof(UnityEngine.Camera).GetProperty("orthographicSize");
|
|
2996
|
+
var getSize = ReflectionHelpers.GetPropertyGetter<UnityEngine.Camera, float>(prop);
|
|
2997
|
+
float size = getSize(UnityEngine.Camera.main);
|
|
2998
|
+
|
|
2999
|
+
// 4) Typed static method invoker (two params)
|
|
3000
|
+
MethodInfo concat = typeof(string).GetMethod(nameof(string.Concat), new[] { typeof(string), typeof(string) });
|
|
3001
|
+
var concat2 = ReflectionHelpers.GetStaticMethodInvoker<string, string, string>(concat);
|
|
3002
|
+
string joined = concat2("Hello ", "World");
|
|
3003
|
+
|
|
3004
|
+
// 5) Low-allocation constructors and collections
|
|
3005
|
+
var newList = ReflectionHelpers.GetParameterlessConstructor<List<int>>();
|
|
3006
|
+
List<int> list = newList();
|
|
3007
|
+
|
|
3008
|
+
var makeVec3Array = ReflectionHelpers.GetArrayCreator(typeof(UnityEngine.Vector3));
|
|
3009
|
+
Array positions = makeVec3Array(256); // Vector3[256]
|
|
3010
|
+
|
|
3011
|
+
IList names = ReflectionHelpers.CreateList(typeof(string), 64); // List<string>
|
|
3012
|
+
|
|
3013
|
+
object intSet = ReflectionHelpers.CreateHashSet(typeof(int), 0); // HashSet<int>
|
|
3014
|
+
var add = ReflectionHelpers.GetHashSetAdder(typeof(int));
|
|
3015
|
+
add(intSet, 1);
|
|
3016
|
+
add(intSet, 2);
|
|
3017
|
+
```
|
|
3018
|
+
|
|
3019
|
+
Tip: Most collection-based APIs accept and fill buffers you provide (List<T>, arrays) to minimize allocations. Prefer passing a preallocated buffer for hot paths.
|
|
3020
|
+
|
|
3021
|
+
### Buffering Pattern
|
|
3022
|
+
|
|
3023
|
+
Many APIs accept a caller-provided buffer (e.g., `List<T>`) and clear it before writing results. Reuse these buffers to avoid per-frame allocations and reduce GC pressure.
|
|
3024
|
+
|
|
3025
|
+
Why it helps
|
|
3026
|
+
|
|
3027
|
+
- Prevents transient allocations in tight loops (AI queries, physics scans).
|
|
3028
|
+
- Keeps GC stable in gameplay spikes (hundreds/thousands of queries).
|
|
3029
|
+
|
|
3030
|
+
Basics
|
|
3031
|
+
|
|
3032
|
+
- Create buffers once per system and reuse them.
|
|
3033
|
+
- APIs that take a `List<T>` will clear it before use and return the same list for chaining.
|
|
3034
|
+
- **Ergonomic benefit**: Because these APIs return the same list you pass in, you can use them directly in `foreach` loops for maximum convenience.
|
|
3035
|
+
- Don't share a single buffer across concurrent operations; allocate one per caller or use pooling.
|
|
3036
|
+
|
|
3037
|
+
**Getting buffers easily:**
|
|
3038
|
+
|
|
3039
|
+
- Use `Buffers<T>.List.Get()` for pooled `List<T>` with automatic return via `Dispose`
|
|
3040
|
+
- Use `WallstopArrayPool<T>.Get()` for pooled arrays with automatic return
|
|
3041
|
+
- Use `WallstopFastArrayPool<T>.Get()` for frequently-used short-lived arrays
|
|
3042
|
+
- See [Pooling utilities](#pooling-utilities) below for detailed examples
|
|
3043
|
+
|
|
3044
|
+
Examples
|
|
3045
|
+
|
|
3046
|
+
```csharp
|
|
3047
|
+
// 2D tree query reuse
|
|
3048
|
+
readonly List<Enemy> _enemiesBuffer = new(capacity: 256);
|
|
3049
|
+
|
|
3050
|
+
void Scan(QuadTree2D<Enemy> tree, Vector2 position, float radius)
|
|
3051
|
+
{
|
|
3052
|
+
tree.GetElementsInRange(position, radius, _enemiesBuffer);
|
|
3053
|
+
for (int i = 0; i < _enemiesBuffer.Count; ++i)
|
|
3054
|
+
{
|
|
3055
|
+
Enemy e = _enemiesBuffer[i];
|
|
3056
|
+
// ... process
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
// Ergonomic pattern: use the returned list directly in foreach
|
|
3061
|
+
readonly List<Enemy> _nearbyBuffer = new(capacity: 128);
|
|
3062
|
+
|
|
3063
|
+
void ProcessNearbyEnemies(QuadTree2D<Enemy> tree, Vector2 position, float radius)
|
|
3064
|
+
{
|
|
3065
|
+
// The API returns the same buffer, so you can chain it into foreach
|
|
3066
|
+
foreach (Enemy enemy in tree.GetElementsInRange(position, radius, _nearbyBuffer))
|
|
3067
|
+
{
|
|
3068
|
+
enemy.ApplyDamage(10f);
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
// Spatial hash with distinct results, approximate distance
|
|
3073
|
+
readonly List<Unit> _units = new(512);
|
|
3074
|
+
hash.Query(center, 10f, _units, distinct: true, exactDistance: false);
|
|
3075
|
+
|
|
3076
|
+
// Components without allocations
|
|
3077
|
+
readonly List<BoxCollider2D> _colliders = new(32);
|
|
3078
|
+
gameObject.GetComponents(_colliders); // buffer is cleared by the API
|
|
3079
|
+
```
|
|
3080
|
+
|
|
3081
|
+
Using the built‑in pool (advanced)
|
|
3082
|
+
|
|
3083
|
+
```csharp
|
|
3084
|
+
using WallstopStudios.UnityHelpers.Utils;
|
|
3085
|
+
using WallstopStudios.UnityHelpers.Core.DataStructure;
|
|
3086
|
+
|
|
3087
|
+
// Get a pooled List<T> and return it automatically via Dispose
|
|
3088
|
+
using PooledResource<List<int>> lease = Buffers<int>.List.Get(out List<int> list);
|
|
3089
|
+
|
|
3090
|
+
// Use list here ...
|
|
3091
|
+
|
|
3092
|
+
// On dispose, list is cleared and returned to the pool
|
|
3093
|
+
```
|
|
3094
|
+
|
|
3095
|
+
Pooling + Buffering combined
|
|
3096
|
+
|
|
3097
|
+
```csharp
|
|
3098
|
+
using WallstopStudios.UnityHelpers.Utils;
|
|
3099
|
+
using WallstopStudios.UnityHelpers.Core.DataStructure;
|
|
3100
|
+
|
|
3101
|
+
// Example: Use pooled buffer for spatial query
|
|
3102
|
+
void FindNearbyEnemies(QuadTree2D<Enemy> tree, Vector2 position)
|
|
3103
|
+
{
|
|
3104
|
+
// Get pooled list - automatically returned when scope exits
|
|
3105
|
+
using var lease = Buffers<Enemy>.List.Get(out List<Enemy> buffer);
|
|
3106
|
+
|
|
3107
|
+
// Use it with spatial query - combines zero-alloc query + pooled buffer!
|
|
3108
|
+
foreach (Enemy enemy in tree.GetElementsInRange(position, 10f, buffer))
|
|
3109
|
+
{
|
|
3110
|
+
enemy.TakeDamage(5f);
|
|
3111
|
+
}
|
|
3112
|
+
// buffer automatically returned to pool here
|
|
3113
|
+
}
|
|
3114
|
+
|
|
3115
|
+
// Array pooling example
|
|
3116
|
+
void ProcessLargeDataset(int size)
|
|
3117
|
+
{
|
|
3118
|
+
using var lease = WallstopArrayPool<float>.Get(size, out float[] buffer);
|
|
3119
|
+
|
|
3120
|
+
// Use buffer for temporary processing
|
|
3121
|
+
for (int i = 0; i < size; i++)
|
|
3122
|
+
{
|
|
3123
|
+
buffer[i] = ComputeValue(i);
|
|
3124
|
+
}
|
|
3125
|
+
|
|
3126
|
+
// buffer automatically returned to pool here
|
|
3127
|
+
}
|
|
3128
|
+
```
|
|
3129
|
+
|
|
3130
|
+
Do / Don’t
|
|
3131
|
+
|
|
3132
|
+
- Do reuse buffers per system or component.
|
|
3133
|
+
- Do treat buffers as temporary scratch space (APIs clear them first).
|
|
3134
|
+
- Don’t keep references to pooled lists beyond their lease lifetime.
|
|
3135
|
+
- Don’t share the same buffer across overlapping async/coroutine work.
|
|
3136
|
+
|
|
3137
|
+
<a id="pooling-utilities"></a>
|
|
3138
|
+
Pooling utilities
|
|
3139
|
+
|
|
3140
|
+
- `Buffers<T>` — pooled collections (List/Stack/Queue/HashSet) with `PooledResource` leases.
|
|
3141
|
+
- Lists: `using var lease = Buffers<Foo>.List.Get(out List<Foo> list);`
|
|
3142
|
+
- Stacks: `using var lease = Buffers<Foo>.Stack.Get(out Stack<Foo> stack);`
|
|
3143
|
+
- HashSets: `using var lease = Buffers<Foo>.HashSet.Get(out HashSet<Foo> set);`
|
|
3144
|
+
- Pattern: acquire → use → Dispose (returns to pool, clears collection).
|
|
3145
|
+
|
|
3146
|
+
- `WallstopArrayPool<T>` — rent arrays by length with automatic return on dispose.
|
|
3147
|
+
- Example: `using var lease = WallstopArrayPool<int>.Get(1024, out int[] buffer);`
|
|
3148
|
+
- Use for temporary processing buffers, sorting, or interop with APIs that require arrays.
|
|
3149
|
+
|
|
3150
|
+
- `WallstopFastArrayPool<T>` — fast array pool specialized for frequent short‑lived arrays.
|
|
3151
|
+
- Example: `using var lease = WallstopFastArrayPool<string>.Get(count, out string[] buffer);`
|
|
3152
|
+
- Used throughout Helpers for high‑frequency editor/runtime operations (e.g., asset searches).
|
|
3153
|
+
|
|
3154
|
+
How pooling + buffering help APIs
|
|
3155
|
+
|
|
3156
|
+
- Spatial queries: pass a reusable `List<T>` to `GetElementsInRange/GetElementsInBounds` and iterate results without allocations.
|
|
3157
|
+
- Component queries: `GetComponents(buffer)` clears and fills your buffer instead of allocating arrays.
|
|
3158
|
+
- Editor utilities: temporary arrays/lists from pools keep import/scan tools snappy, especially inside loops.
|
|
3159
|
+
|
|
3160
|
+
## Dependency Injection Integrations
|
|
3161
|
+
|
|
3162
|
+
- Auto-detected packages
|
|
3163
|
+
- Zenject/Extenject: `com.extenject.zenject`, `com.modesttree.zenject`, `com.svermeulen.extenject`
|
|
3164
|
+
- VContainer: `jp.cysharp.vcontainer`, `jp.hadashikick.vcontainer`
|
|
3165
|
+
- Manual or source imports (no UPM)
|
|
3166
|
+
- Add scripting defines in `Project Settings > Player > Other Settings > Scripting Define Symbols`:
|
|
3167
|
+
- `ZENJECT_PRESENT` when Zenject/Extenject is present
|
|
3168
|
+
- `VCONTAINER_PRESENT` when VContainer is present
|
|
3169
|
+
- Add the define per target platform (e.g., Standalone, Android, iOS).
|
|
3170
|
+
- Notes
|
|
3171
|
+
- When the define is present, optional assemblies under `Runtime/Integrations/*` compile automatically and expose helpers like `RelationalComponentsInstaller` (Zenject) and `RegisterRelationalComponents()` (VContainer).
|
|
3172
|
+
- If you use UPM, no manual defines are required — the package IDs above trigger symbols via `versionDefines` in the asmdefs.
|
|
3173
|
+
- For test scenarios without LifetimeScope (VContainer) or SceneContext (Zenject), see [DI Integrations: Testing and Edge Cases](RELATIONAL_COMPONENTS.md#di-integrations-testing-and-edge-cases) for step‑by‑step patterns.
|
|
3174
|
+
|
|
3175
|
+
- Quick start
|
|
3176
|
+
- VContainer: in your `LifetimeScope.Configure`, call `builder.RegisterRelationalComponents()`.
|
|
3177
|
+
- Zenject: add `RelationalComponentsInstaller` to your `SceneContext` (toggle scene scan if desired).
|
|
3178
|
+
|
|
3179
|
+
```csharp
|
|
3180
|
+
// VContainer — LifetimeScope
|
|
3181
|
+
using VContainer;
|
|
3182
|
+
using VContainer.Unity;
|
|
3183
|
+
using WallstopStudios.UnityHelpers.Integrations.VContainer;
|
|
3184
|
+
protected override void Configure(IContainerBuilder builder)
|
|
3185
|
+
{
|
|
3186
|
+
builder.RegisterRelationalComponents();
|
|
3187
|
+
}
|
|
3188
|
+
|
|
3189
|
+
// Zenject — prefab instantiation with DI + relations
|
|
3190
|
+
using Zenject;
|
|
3191
|
+
using WallstopStudios.UnityHelpers.Integrations.Zenject;
|
|
3192
|
+
var enemy = Container.InstantiateComponentWithRelations(enemyPrefab, parent);
|
|
3193
|
+
```
|
|
3194
|
+
|
|
3195
|
+
See the full guide with scenarios, troubleshooting, and testing patterns: [Relational Components Guide](RELATIONAL_COMPONENTS.md)
|